blob: d702f11f26eea8c88337c65ac8f339fefa45ef45 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
9#include <string>
[email protected]95d88ffe2010-02-04 21:25:3310#include <vector>
[email protected]77848d12008-11-14 00:00:2211
[email protected]2d731a32010-04-29 01:04:0612#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3013#include "base/compiler_specific.h"
[email protected]95d88ffe2010-02-04 21:25:3314#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:5215#include "base/files/file_path.h"
[email protected]f3da152d2012-06-02 01:00:5716#include "base/json/json_writer.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4718#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4919#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4720#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0521#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3322#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3523#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1224#include "net/base/capturing_net_log.h"
[email protected]bacff652009-03-31 17:50:3325#include "net/base/completion_callback.h"
[email protected]58e32bb2013-01-21 18:23:2526#include "net/base/load_timing_info.h"
27#include "net/base/load_timing_info_test_util.h"
[email protected]169d0012010-05-10 23:20:1228#include "net/base/net_log.h"
29#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3130#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5231#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4032#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0633#include "net/base/upload_bytes_element_reader.h"
[email protected]329b68b2012-11-14 17:54:2734#include "net/base/upload_data_stream.h"
[email protected]d98961652012-09-11 20:27:2135#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1136#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1637#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5338#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2439#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1240#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0041#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2942#include "net/http/http_auth_handler_ntlm.h"
[email protected]0877e3d2009-10-17 22:29:5743#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5244#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5645#include "net/http/http_network_session_peer.h"
[email protected]17291a022011-10-10 07:32:5346#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5747#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3848#include "net/http/http_stream_factory.h"
initial.commit586acc5fe2008-07-26 22:42:5249#include "net/http/http_transaction_unittest.h"
[email protected]51fff29d2008-12-19 22:17:5350#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0351#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1152#include "net/proxy/proxy_resolver.h"
53#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4454#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0355#include "net/socket/client_socket_pool_manager.h"
[email protected]a42dbd142011-11-17 16:42:0256#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0757#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4458#include "net/socket/socket_test_util.h"
59#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5460#include "net/spdy/spdy_framer.h"
61#include "net/spdy/spdy_session.h"
62#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0263#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5764#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0365#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5766#include "net/ssl/ssl_config_service_defaults.h"
67#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1168#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4469#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5270#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1571#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2772#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5273
[email protected]ad65a3e2013-12-25 18:18:0174using base::ASCIIToUTF16;
75
initial.commit586acc5fe2008-07-26 22:42:5276//-----------------------------------------------------------------------------
77
[email protected]13c8a092010-07-29 06:15:4478namespace {
79
[email protected]42cba2fb2013-03-29 19:58:5780const base::string16 kBar(ASCIIToUTF16("bar"));
81const base::string16 kBar2(ASCIIToUTF16("bar2"));
82const base::string16 kBar3(ASCIIToUTF16("bar3"));
83const base::string16 kBaz(ASCIIToUTF16("baz"));
84const base::string16 kFirst(ASCIIToUTF16("first"));
85const base::string16 kFoo(ASCIIToUTF16("foo"));
86const base::string16 kFoo2(ASCIIToUTF16("foo2"));
87const base::string16 kFoo3(ASCIIToUTF16("foo3"));
88const base::string16 kFou(ASCIIToUTF16("fou"));
89const base::string16 kSecond(ASCIIToUTF16("second"));
90const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
91const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4492
[email protected]e5c026642012-03-17 00:14:0293int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
94 return session->GetTransportSocketPool(
95 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
96}
97
98int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
99 return session->GetSSLSocketPool(
100 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
101}
102
[email protected]043b68c82013-08-22 23:41:52103bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
104 return session->GetTransportSocketPool(
105 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
106}
107
[email protected]f3da152d2012-06-02 01:00:57108// Takes in a Value created from a NetLogHttpResponseParameter, and returns
109// a JSONified list of headers as a single string. Uses single quotes instead
110// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27111bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57112 if (!params)
113 return false;
[email protected]ea5ef4c2013-06-13 22:50:27114 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57115 if (!params->GetList("headers", &header_list))
116 return false;
117 std::string double_quote_headers;
118 base::JSONWriter::Write(header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28119 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57120 return true;
121}
122
[email protected]029c83b62013-01-24 05:28:20123// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
124// used.
125void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
126 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25127 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
128
[email protected]029c83b62013-01-24 05:28:20129 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
130 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
131
132 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
133 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25134
135 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25136
[email protected]3b23a222013-05-15 21:33:25137 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25138 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
139 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25140 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25141}
142
[email protected]029c83b62013-01-24 05:28:20143// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
144// used.
[email protected]58e32bb2013-01-21 18:23:25145void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
146 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20147 EXPECT_FALSE(load_timing_info.socket_reused);
148 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
149
150 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
151 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
152
153 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25154 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20155 EXPECT_LE(load_timing_info.connect_timing.connect_end,
156 load_timing_info.send_start);
157
158 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20159
[email protected]3b23a222013-05-15 21:33:25160 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20161 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
162 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25163 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20164}
165
166// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
167// used.
168void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
169 EXPECT_TRUE(load_timing_info.socket_reused);
170 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
171
172 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
173
174 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
175 EXPECT_LE(load_timing_info.proxy_resolve_start,
176 load_timing_info.proxy_resolve_end);
177 EXPECT_LE(load_timing_info.proxy_resolve_end,
178 load_timing_info.send_start);
179 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20180
[email protected]3b23a222013-05-15 21:33:25181 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20182 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
183 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25184 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20185}
186
187// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
188// used.
189void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
190 int connect_timing_flags) {
191 EXPECT_FALSE(load_timing_info.socket_reused);
192 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
193
194 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
195 EXPECT_LE(load_timing_info.proxy_resolve_start,
196 load_timing_info.proxy_resolve_end);
197 EXPECT_LE(load_timing_info.proxy_resolve_end,
198 load_timing_info.connect_timing.connect_start);
199 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
200 connect_timing_flags);
201 EXPECT_LE(load_timing_info.connect_timing.connect_end,
202 load_timing_info.send_start);
203
204 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20205
[email protected]3b23a222013-05-15 21:33:25206 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20207 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
208 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25209 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25210}
211
[email protected]13c8a092010-07-29 06:15:44212} // namespace
213
[email protected]89ceba9a2009-03-21 03:46:06214namespace net {
215
[email protected]448d4ca52012-03-04 04:12:23216namespace {
217
[email protected]c6bf8152012-12-02 07:43:34218HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
219 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14220}
221
[email protected]448d4ca52012-03-04 04:12:23222} // namespace
223
[email protected]23e482282013-06-14 16:08:02224class HttpNetworkTransactionTest
225 : public PlatformTest,
226 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03227 public:
[email protected]23e482282013-06-14 16:08:02228 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03229 // Important to restore the per-pool limit first, since the pool limit must
230 // always be greater than group limit, and the tests reduce both limits.
231 ClientSocketPoolManager::set_max_sockets_per_pool(
232 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
233 ClientSocketPoolManager::set_max_sockets_per_group(
234 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
235 }
236
[email protected]e3ceb682011-06-28 23:55:46237 protected:
[email protected]23e482282013-06-14 16:08:02238 HttpNetworkTransactionTest()
239 : spdy_util_(GetParam()),
240 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03241 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
242 HttpNetworkSession::NORMAL_SOCKET_POOL)),
243 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
244 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
245 }
[email protected]bb88e1d32013-05-03 23:11:07246
[email protected]e3ceb682011-06-28 23:55:46247 struct SimpleGetHelperResult {
248 int rv;
249 std::string status_line;
250 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19251 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25252 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46253 };
254
[email protected]2ff8b312010-04-26 22:20:54255 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50256 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34257 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54258 }
259
[email protected]0e75a732008-10-16 20:36:09260 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50261 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34262 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09263 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34264 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09265 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50266 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34267 base::MessageLoop::current()->RunUntilIdle();
[email protected]c54c6962013-02-01 04:53:19268 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:16269 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]0e75a732008-10-16 20:36:09270 }
271
[email protected]8a0fc822013-06-27 20:52:43272 // This is the expected return from a current server advertising SPDY.
273 std::string GetAlternateProtocolHttpHeader() {
274 return
275 std::string("Alternate-Protocol: 443:") +
276 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
277 "\r\n\r\n";
278 }
279
[email protected]202965992011-12-07 23:04:51280 // Either |write_failure| specifies a write failure or |read_failure|
281 // specifies a read failure when using a reused socket. In either case, the
282 // failure should cause the network transaction to resend the request, and the
283 // other argument should be NULL.
284 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
285 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52286
[email protected]a34f61ee2014-03-18 20:59:49287 // Either |write_failure| specifies a write failure or |read_failure|
288 // specifies a read failure when using a reused socket. In either case, the
289 // failure should cause the network transaction to resend the request, and the
290 // other argument should be NULL.
291 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10292 const MockRead* read_failure,
293 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49294
[email protected]5a60c8b2011-10-19 20:14:29295 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
296 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15297 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52298
[email protected]ff007e162009-05-23 09:13:15299 HttpRequestInfo request;
300 request.method = "GET";
301 request.url = GURL("http://www.google.com/");
302 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52303
[email protected]58e32bb2013-01-21 18:23:25304 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07305 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27307 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07308 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27309
[email protected]5a60c8b2011-10-19 20:14:29310 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07311 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29312 }
initial.commit586acc5fe2008-07-26 22:42:52313
[email protected]49639fa2011-12-20 23:22:41314 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52315
[email protected]c47c0372014-03-12 23:07:02316 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41317 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15318 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52319
[email protected]ff007e162009-05-23 09:13:15320 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25321
322 // Even in the failure cases that use this function, connections are always
323 // successfully established before the error.
324 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
325 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
326
[email protected]ff007e162009-05-23 09:13:15327 if (out.rv != OK)
328 return out;
329
330 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50331 // Can't use ASSERT_* inside helper functions like this, so
332 // return an error.
[email protected]90499482013-06-01 00:39:50333 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50334 out.rv = ERR_UNEXPECTED;
335 return out;
336 }
[email protected]ff007e162009-05-23 09:13:15337 out.status_line = response->headers->GetStatusLine();
338
[email protected]80a09a82012-11-16 17:40:06339 EXPECT_EQ("127.0.0.1", response->socket_address.host());
340 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19341
[email protected]ff007e162009-05-23 09:13:15342 rv = ReadTransaction(trans.get(), &out.response_data);
343 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40344
[email protected]f3da152d2012-06-02 01:00:57345 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40346 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39347 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40348 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12349 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39350 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40351 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39352 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
353 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15354
[email protected]f3da152d2012-06-02 01:00:57355 std::string line;
356 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
357 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
358
[email protected]79e1fd62013-06-20 06:50:04359 HttpRequestHeaders request_headers;
360 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
361 std::string value;
362 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
363 EXPECT_EQ("www.google.com", value);
364 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
365 EXPECT_EQ("keep-alive", value);
366
367 std::string response_headers;
368 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
369 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
370 response_headers);
[email protected]3deb9a52010-11-11 00:24:40371
[email protected]b8015c42013-12-24 15:18:19372 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47373 return out;
[email protected]ff007e162009-05-23 09:13:15374 }
initial.commit586acc5fe2008-07-26 22:42:52375
[email protected]5a60c8b2011-10-19 20:14:29376 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
377 size_t reads_count) {
378 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
379 StaticSocketDataProvider* data[] = { &reads };
380 return SimpleGetHelperForData(data, 1);
381 }
382
[email protected]b8015c42013-12-24 15:18:19383 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
384 int64 size = 0;
385 for (size_t i = 0; i < reads_count; ++i)
386 size += data_reads[i].data_len;
387 return size;
388 }
389
[email protected]ff007e162009-05-23 09:13:15390 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
391 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52392
[email protected]ff007e162009-05-23 09:13:15393 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07394
395 void BypassHostCacheOnRefreshHelper(int load_flags);
396
397 void CheckErrorIsPassedBack(int error, IoMode mode);
398
[email protected]4bd46222013-05-14 19:32:23399 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07400 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03401
402 // Original socket limits. Some tests set these. Safest to always restore
403 // them once each test has been run.
404 int old_max_group_sockets_;
405 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15406};
[email protected]231d5a32008-09-13 00:45:27407
[email protected]23e482282013-06-14 16:08:02408INSTANTIATE_TEST_CASE_P(
409 NextProto,
410 HttpNetworkTransactionTest,
[email protected]b05bcaa32013-10-06 05:26:02411 testing::Values(kProtoDeprecatedSPDY2,
412 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
[email protected]88a332622013-07-30 07:13:32413 kProtoHTTP2Draft04));
[email protected]23e482282013-06-14 16:08:02414
[email protected]448d4ca52012-03-04 04:12:23415namespace {
416
[email protected]1826a402014-01-08 15:40:48417class BeforeNetworkStartHandler {
418 public:
419 explicit BeforeNetworkStartHandler(bool defer)
420 : defer_on_before_network_start_(defer),
421 observed_before_network_start_(false) {}
422
423 void OnBeforeNetworkStart(bool* defer) {
424 *defer = defer_on_before_network_start_;
425 observed_before_network_start_ = true;
426 }
427
428 bool observed_before_network_start() const {
429 return observed_before_network_start_;
430 }
431
432 private:
433 const bool defer_on_before_network_start_;
434 bool observed_before_network_start_;
435
436 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
437};
438
[email protected]15a5ccf82008-10-23 19:57:43439// Fill |str| with a long header list that consumes >= |size| bytes.
440void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19441 const char* row =
442 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
443 const int sizeof_row = strlen(row);
444 const int num_rows = static_cast<int>(
445 ceil(static_cast<float>(size) / sizeof_row));
446 const int sizeof_data = num_rows * sizeof_row;
447 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43448 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51449
[email protected]4ddaf2502008-10-23 18:26:19450 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43451 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19452}
453
[email protected]385a4672009-03-11 22:21:29454// Alternative functions that eliminate randomness and dependency on the local
455// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20456void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29457 static const uint8 bytes[] = {
458 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
459 };
460 static size_t current_byte = 0;
461 for (size_t i = 0; i < n; ++i) {
462 output[i] = bytes[current_byte++];
463 current_byte %= arraysize(bytes);
464 }
465}
466
[email protected]fe2bc6a2009-03-23 16:52:20467void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29468 static const uint8 bytes[] = {
469 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
470 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
471 };
472 static size_t current_byte = 0;
473 for (size_t i = 0; i < n; ++i) {
474 output[i] = bytes[current_byte++];
475 current_byte %= arraysize(bytes);
476 }
477}
478
[email protected]fe2bc6a2009-03-23 16:52:20479std::string MockGetHostName() {
480 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29481}
482
[email protected]e60e47a2010-07-14 03:37:18483template<typename ParentPool>
484class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31485 public:
[email protected]9e1bdd32011-02-03 21:48:34486 CaptureGroupNameSocketPool(HostResolver* host_resolver,
487 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18488
[email protected]d80a4322009-08-14 07:07:49489 const std::string last_group_name_received() const {
490 return last_group_name_;
491 }
492
[email protected]684970b2009-08-14 04:54:46493 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49494 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31495 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31496 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41497 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53498 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31499 last_group_name_ = group_name;
500 return ERR_IO_PENDING;
501 }
[email protected]04e5be32009-06-26 20:00:31502 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21503 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31504 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44505 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19506 int id) {}
[email protected]04e5be32009-06-26 20:00:31507 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31508 virtual int IdleSocketCount() const {
509 return 0;
510 }
511 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
512 return 0;
513 }
514 virtual LoadState GetLoadState(const std::string& group_name,
515 const ClientSocketHandle* handle) const {
516 return LOAD_STATE_IDLE;
517 }
[email protected]a796bcec2010-03-22 17:17:26518 virtual base::TimeDelta ConnectionTimeout() const {
519 return base::TimeDelta();
520 }
[email protected]d80a4322009-08-14 07:07:49521
522 private:
[email protected]04e5be32009-06-26 20:00:31523 std::string last_group_name_;
524};
525
[email protected]ab739042011-04-07 15:22:28526typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
527CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13528typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
529CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06530typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11531CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18532typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
533CaptureGroupNameSSLSocketPool;
534
535template<typename ParentPool>
536CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34537 HostResolver* host_resolver,
538 CertVerifier* /* cert_verifier */)
539 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18540
541template<>
[email protected]2df19bb2010-08-25 20:13:46542CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34543 HostResolver* host_resolver,
544 CertVerifier* /* cert_verifier */)
545 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46546
[email protected]007b3f82013-04-09 08:46:45547template <>
[email protected]e60e47a2010-07-14 03:37:18548CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34549 HostResolver* host_resolver,
550 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45551 : SSLClientSocketPool(0,
552 0,
553 NULL,
554 host_resolver,
555 cert_verifier,
556 NULL,
557 NULL,
[email protected]284303b62013-11-28 15:11:54558 NULL,
[email protected]007b3f82013-04-09 08:46:45559 std::string(),
560 NULL,
561 NULL,
562 NULL,
563 NULL,
564 NULL,
565 NULL) {}
[email protected]2227c692010-05-04 15:36:11566
[email protected]231d5a32008-09-13 00:45:27567//-----------------------------------------------------------------------------
568
[email protected]79cb5c12011-09-12 13:12:04569// Helper functions for validating that AuthChallengeInfo's are correctly
570// configured for common cases.
571bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
572 if (!auth_challenge)
573 return false;
574 EXPECT_FALSE(auth_challenge->is_proxy);
575 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
576 EXPECT_EQ("MyRealm1", auth_challenge->realm);
577 EXPECT_EQ("basic", auth_challenge->scheme);
578 return true;
579}
580
581bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
582 if (!auth_challenge)
583 return false;
584 EXPECT_TRUE(auth_challenge->is_proxy);
585 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
586 EXPECT_EQ("MyRealm1", auth_challenge->realm);
587 EXPECT_EQ("basic", auth_challenge->scheme);
588 return true;
589}
590
591bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
592 if (!auth_challenge)
593 return false;
594 EXPECT_FALSE(auth_challenge->is_proxy);
595 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
596 EXPECT_EQ("digestive", auth_challenge->realm);
597 EXPECT_EQ("digest", auth_challenge->scheme);
598 return true;
599}
600
601bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
602 if (!auth_challenge)
603 return false;
604 EXPECT_FALSE(auth_challenge->is_proxy);
605 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
606 EXPECT_EQ(std::string(), auth_challenge->realm);
607 EXPECT_EQ("ntlm", auth_challenge->scheme);
608 return true;
609}
610
[email protected]448d4ca52012-03-04 04:12:23611} // namespace
612
[email protected]23e482282013-06-14 16:08:02613TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07614 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40615 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07616 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27617}
618
[email protected]23e482282013-06-14 16:08:02619TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27620 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35621 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
622 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06623 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27624 };
[email protected]31a2bfe2010-02-09 08:03:39625 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
626 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42627 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27628 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
629 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19630 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
631 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27632}
633
634// Response with no status line.
[email protected]23e482282013-06-14 16:08:02635TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27636 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35637 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06638 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27639 };
[email protected]31a2bfe2010-02-09 08:03:39640 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
641 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42642 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27643 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
644 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19645 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
646 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27647}
648
649// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02650TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27651 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35652 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06653 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27654 };
[email protected]31a2bfe2010-02-09 08:03:39655 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
656 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42657 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27658 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
659 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19660 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
661 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27662}
663
664// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02665TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27666 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35667 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06668 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27669 };
[email protected]31a2bfe2010-02-09 08:03:39670 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
671 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42672 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27673 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
674 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19675 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
676 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27677}
678
679// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02680TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27681 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35682 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06683 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27684 };
[email protected]31a2bfe2010-02-09 08:03:39685 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
686 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42687 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25688 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
689 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19690 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
691 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27692}
693
694// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02695TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27696 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35697 MockRead("\n"),
698 MockRead("\n"),
699 MockRead("Q"),
700 MockRead("J"),
701 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06702 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27703 };
[email protected]31a2bfe2010-02-09 08:03:39704 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
705 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42706 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27707 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
708 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19709 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
710 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27711}
712
713// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02714TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27715 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35716 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06717 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27718 };
[email protected]31a2bfe2010-02-09 08:03:39719 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
720 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42721 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27722 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
723 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19724 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
725 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52726}
727
[email protected]f9d44aa2008-09-23 23:57:17728// Simulate a 204 response, lacking a Content-Length header, sent over a
729// persistent connection. The response should still terminate since a 204
730// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02731TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19732 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17733 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35734 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19735 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06736 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17737 };
[email protected]31a2bfe2010-02-09 08:03:39738 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
739 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42740 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17741 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
742 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19743 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
744 int64 response_size = reads_size - strlen(junk);
745 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17746}
747
[email protected]0877e3d2009-10-17 22:29:57748// A simple request using chunked encoding with some extra data after.
749// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02750TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19751 std::string final_chunk = "0\r\n\r\n";
752 std::string extra_data = "HTTP/1.1 200 OK\r\n";
753 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57754 MockRead data_reads[] = {
755 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
756 MockRead("5\r\nHello\r\n"),
757 MockRead("1\r\n"),
758 MockRead(" \r\n"),
759 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19760 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06761 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57762 };
[email protected]31a2bfe2010-02-09 08:03:39763 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
764 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57765 EXPECT_EQ(OK, out.rv);
766 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
767 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19768 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
769 int64 response_size = reads_size - extra_data.size();
770 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57771}
772
[email protected]9fe44f52010-09-23 18:36:00773// Next tests deal with http://crbug.com/56344.
774
[email protected]23e482282013-06-14 16:08:02775TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00776 MultipleContentLengthHeadersNoTransferEncoding) {
777 MockRead data_reads[] = {
778 MockRead("HTTP/1.1 200 OK\r\n"),
779 MockRead("Content-Length: 10\r\n"),
780 MockRead("Content-Length: 5\r\n\r\n"),
781 };
782 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
783 arraysize(data_reads));
784 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
785}
786
[email protected]23e482282013-06-14 16:08:02787TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04788 DuplicateContentLengthHeadersNoTransferEncoding) {
789 MockRead data_reads[] = {
790 MockRead("HTTP/1.1 200 OK\r\n"),
791 MockRead("Content-Length: 5\r\n"),
792 MockRead("Content-Length: 5\r\n\r\n"),
793 MockRead("Hello"),
794 };
795 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
796 arraysize(data_reads));
797 EXPECT_EQ(OK, out.rv);
798 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
799 EXPECT_EQ("Hello", out.response_data);
800}
801
[email protected]23e482282013-06-14 16:08:02802TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04803 ComplexContentLengthHeadersNoTransferEncoding) {
804 // More than 2 dupes.
805 {
806 MockRead data_reads[] = {
807 MockRead("HTTP/1.1 200 OK\r\n"),
808 MockRead("Content-Length: 5\r\n"),
809 MockRead("Content-Length: 5\r\n"),
810 MockRead("Content-Length: 5\r\n\r\n"),
811 MockRead("Hello"),
812 };
813 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
814 arraysize(data_reads));
815 EXPECT_EQ(OK, out.rv);
816 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
817 EXPECT_EQ("Hello", out.response_data);
818 }
819 // HTTP/1.0
820 {
821 MockRead data_reads[] = {
822 MockRead("HTTP/1.0 200 OK\r\n"),
823 MockRead("Content-Length: 5\r\n"),
824 MockRead("Content-Length: 5\r\n"),
825 MockRead("Content-Length: 5\r\n\r\n"),
826 MockRead("Hello"),
827 };
828 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
829 arraysize(data_reads));
830 EXPECT_EQ(OK, out.rv);
831 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
832 EXPECT_EQ("Hello", out.response_data);
833 }
834 // 2 dupes and one mismatched.
835 {
836 MockRead data_reads[] = {
837 MockRead("HTTP/1.1 200 OK\r\n"),
838 MockRead("Content-Length: 10\r\n"),
839 MockRead("Content-Length: 10\r\n"),
840 MockRead("Content-Length: 5\r\n\r\n"),
841 };
842 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
843 arraysize(data_reads));
844 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
845 }
846}
847
[email protected]23e482282013-06-14 16:08:02848TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00849 MultipleContentLengthHeadersTransferEncoding) {
850 MockRead data_reads[] = {
851 MockRead("HTTP/1.1 200 OK\r\n"),
852 MockRead("Content-Length: 666\r\n"),
853 MockRead("Content-Length: 1337\r\n"),
854 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
855 MockRead("5\r\nHello\r\n"),
856 MockRead("1\r\n"),
857 MockRead(" \r\n"),
858 MockRead("5\r\nworld\r\n"),
859 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06860 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00861 };
862 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
863 arraysize(data_reads));
864 EXPECT_EQ(OK, out.rv);
865 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
866 EXPECT_EQ("Hello world", out.response_data);
867}
868
[email protected]1628fe92011-10-04 23:04:55869// Next tests deal with http://crbug.com/98895.
870
871// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02872TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55873 MockRead data_reads[] = {
874 MockRead("HTTP/1.1 200 OK\r\n"),
875 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
876 MockRead("Content-Length: 5\r\n\r\n"),
877 MockRead("Hello"),
878 };
879 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
880 arraysize(data_reads));
881 EXPECT_EQ(OK, out.rv);
882 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
883 EXPECT_EQ("Hello", out.response_data);
884}
885
[email protected]54a9c6e52012-03-21 20:10:59886// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02887TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59888 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55889 MockRead data_reads[] = {
890 MockRead("HTTP/1.1 200 OK\r\n"),
891 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
892 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
893 MockRead("Content-Length: 5\r\n\r\n"),
894 MockRead("Hello"),
895 };
896 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
897 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59898 EXPECT_EQ(OK, out.rv);
899 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
900 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55901}
902
903// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02904TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55905 MockRead data_reads[] = {
906 MockRead("HTTP/1.1 200 OK\r\n"),
907 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
908 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
909 MockRead("Content-Length: 5\r\n\r\n"),
910 MockRead("Hello"),
911 };
912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
914 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
915}
916
[email protected]54a9c6e52012-03-21 20:10:59917// Checks that two identical Location headers result in no error.
918// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02919TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55920 MockRead data_reads[] = {
921 MockRead("HTTP/1.1 302 Redirect\r\n"),
922 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59923 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55924 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06925 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55926 };
927
928 HttpRequestInfo request;
929 request.method = "GET";
930 request.url = GURL("http://redirect.com/");
931 request.load_flags = 0;
932
[email protected]3fe8d2f82013-10-17 08:56:07933 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55934 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07935 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55936
937 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07938 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55939
[email protected]49639fa2011-12-20 23:22:41940 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55941
[email protected]49639fa2011-12-20 23:22:41942 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55943 EXPECT_EQ(ERR_IO_PENDING, rv);
944
945 EXPECT_EQ(OK, callback.WaitForResult());
946
947 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50948 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55949 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
950 std::string url;
951 EXPECT_TRUE(response->headers->IsRedirect(&url));
952 EXPECT_EQ("http://good.com/", url);
953}
954
[email protected]1628fe92011-10-04 23:04:55955// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02956TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55957 MockRead data_reads[] = {
958 MockRead("HTTP/1.1 302 Redirect\r\n"),
959 MockRead("Location: http://good.com/\r\n"),
960 MockRead("Location: http://evil.com/\r\n"),
961 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06962 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55963 };
964 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
965 arraysize(data_reads));
966 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
967}
968
[email protected]ef0faf2e72009-03-05 23:27:23969// Do a request using the HEAD method. Verify that we don't try to read the
970// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02971TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42972 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23973 request.method = "HEAD";
974 request.url = GURL("http://www.google.com/");
975 request.load_flags = 0;
976
[email protected]3fe8d2f82013-10-17 08:56:07977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27978 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27980
[email protected]ef0faf2e72009-03-05 23:27:23981 MockWrite data_writes1[] = {
982 MockWrite("HEAD / HTTP/1.1\r\n"
983 "Host: www.google.com\r\n"
984 "Connection: keep-alive\r\n"
985 "Content-Length: 0\r\n\r\n"),
986 };
987 MockRead data_reads1[] = {
988 MockRead("HTTP/1.1 404 Not Found\r\n"),
989 MockRead("Server: Blah\r\n"),
990 MockRead("Content-Length: 1234\r\n\r\n"),
991
992 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06993 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23994 };
995
[email protected]31a2bfe2010-02-09 08:03:39996 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
997 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07998 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23999
[email protected]49639fa2011-12-20 23:22:411000 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231001
[email protected]49639fa2011-12-20 23:22:411002 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421003 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231004
1005 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421006 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231007
[email protected]1c773ea12009-04-28 19:58:421008 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501009 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231010
1011 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501012 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231013 EXPECT_EQ(1234, response->headers->GetContentLength());
1014 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1015
1016 std::string server_header;
1017 void* iter = NULL;
1018 bool has_server_header = response->headers->EnumerateHeader(
1019 &iter, "Server", &server_header);
1020 EXPECT_TRUE(has_server_header);
1021 EXPECT_EQ("Blah", server_header);
1022
1023 // Reading should give EOF right away, since there is no message body
1024 // (despite non-zero content-length).
1025 std::string response_data;
1026 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421027 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231028 EXPECT_EQ("", response_data);
1029}
1030
[email protected]23e482282013-06-14 16:08:021031TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071032 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521033
1034 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351035 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1036 MockRead("hello"),
1037 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1038 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061039 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521040 };
[email protected]31a2bfe2010-02-09 08:03:391041 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071042 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521043
[email protected]0b0bf032010-09-21 18:08:501044 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521045 "hello", "world"
1046 };
1047
1048 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421049 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521050 request.method = "GET";
1051 request.url = GURL("http://www.google.com/");
1052 request.load_flags = 0;
1053
[email protected]262eec82013-03-19 21:01:361054 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271056
[email protected]49639fa2011-12-20 23:22:411057 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521058
[email protected]49639fa2011-12-20 23:22:411059 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421060 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521061
1062 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421063 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521064
[email protected]1c773ea12009-04-28 19:58:421065 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501066 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521067
[email protected]90499482013-06-01 00:39:501068 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251069 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521070
1071 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571072 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421073 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251074 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521075 }
1076}
1077
[email protected]23e482282013-06-14 16:08:021078TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061079 ScopedVector<UploadElementReader> element_readers;
1080 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201081 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271082
[email protected]1c773ea12009-04-28 19:58:421083 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521084 request.method = "POST";
1085 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271086 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521087 request.load_flags = 0;
1088
[email protected]3fe8d2f82013-10-17 08:56:071089 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271090 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071091 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271092
initial.commit586acc5fe2008-07-26 22:42:521093 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351094 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1095 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1096 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061097 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521098 };
[email protected]31a2bfe2010-02-09 08:03:391099 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071100 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521101
[email protected]49639fa2011-12-20 23:22:411102 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521103
[email protected]49639fa2011-12-20 23:22:411104 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421105 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521106
1107 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421108 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521109
[email protected]1c773ea12009-04-28 19:58:421110 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501111 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521112
[email protected]90499482013-06-01 00:39:501113 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251114 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521115
1116 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571117 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421118 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251119 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521120}
1121
[email protected]3a2d3662009-03-27 03:49:141122// This test is almost the same as Ignores100 above, but the response contains
1123// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571124// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021125TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421126 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141127 request.method = "GET";
1128 request.url = GURL("http://www.foo.com/");
1129 request.load_flags = 0;
1130
[email protected]3fe8d2f82013-10-17 08:56:071131 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271132 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271134
[email protected]3a2d3662009-03-27 03:49:141135 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571136 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1137 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141138 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061139 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141140 };
[email protected]31a2bfe2010-02-09 08:03:391141 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071142 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141143
[email protected]49639fa2011-12-20 23:22:411144 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141145
[email protected]49639fa2011-12-20 23:22:411146 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421147 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141148
1149 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421150 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141151
[email protected]1c773ea12009-04-28 19:58:421152 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501153 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141154
[email protected]90499482013-06-01 00:39:501155 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141156 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1157
1158 std::string response_data;
1159 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421160 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141161 EXPECT_EQ("hello world", response_data);
1162}
1163
[email protected]23e482282013-06-14 16:08:021164TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381165 HttpRequestInfo request;
1166 request.method = "POST";
1167 request.url = GURL("http://www.foo.com/");
1168 request.load_flags = 0;
1169
[email protected]3fe8d2f82013-10-17 08:56:071170 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271171 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071172 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271173
[email protected]ee9410e72010-01-07 01:42:381174 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061175 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1176 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381177 };
[email protected]31a2bfe2010-02-09 08:03:391178 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071179 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381180
[email protected]49639fa2011-12-20 23:22:411181 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381182
[email protected]49639fa2011-12-20 23:22:411183 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381184 EXPECT_EQ(ERR_IO_PENDING, rv);
1185
1186 rv = callback.WaitForResult();
1187 EXPECT_EQ(OK, rv);
1188
1189 std::string response_data;
1190 rv = ReadTransaction(trans.get(), &response_data);
1191 EXPECT_EQ(OK, rv);
1192 EXPECT_EQ("", response_data);
1193}
1194
[email protected]23e482282013-06-14 16:08:021195TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381196 HttpRequestInfo request;
1197 request.method = "POST";
1198 request.url = GURL("http://www.foo.com/");
1199 request.load_flags = 0;
1200
[email protected]3fe8d2f82013-10-17 08:56:071201 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271202 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1204
[email protected]cb9bf6ca2011-01-28 13:15:271205
[email protected]ee9410e72010-01-07 01:42:381206 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061207 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381208 };
[email protected]31a2bfe2010-02-09 08:03:391209 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071210 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381211
[email protected]49639fa2011-12-20 23:22:411212 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381213
[email protected]49639fa2011-12-20 23:22:411214 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381215 EXPECT_EQ(ERR_IO_PENDING, rv);
1216
1217 rv = callback.WaitForResult();
1218 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1219}
1220
[email protected]23e482282013-06-14 16:08:021221void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511222 const MockWrite* write_failure,
1223 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421224 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521225 request.method = "GET";
1226 request.url = GURL("http://www.foo.com/");
1227 request.load_flags = 0;
1228
[email protected]58e32bb2013-01-21 18:23:251229 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071230 session_deps_.net_log = &net_log;
1231 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271232
[email protected]202965992011-12-07 23:04:511233 // Written data for successfully sending both requests.
1234 MockWrite data1_writes[] = {
1235 MockWrite("GET / HTTP/1.1\r\n"
1236 "Host: www.foo.com\r\n"
1237 "Connection: keep-alive\r\n\r\n"),
1238 MockWrite("GET / HTTP/1.1\r\n"
1239 "Host: www.foo.com\r\n"
1240 "Connection: keep-alive\r\n\r\n")
1241 };
1242
1243 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521244 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351245 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1246 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061247 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521248 };
[email protected]202965992011-12-07 23:04:511249
1250 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491251 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511252 data1_writes[1] = *write_failure;
1253 } else {
1254 ASSERT_TRUE(read_failure);
1255 data1_reads[2] = *read_failure;
1256 }
1257
1258 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1259 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071260 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521261
1262 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351263 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1264 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061265 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521266 };
[email protected]31a2bfe2010-02-09 08:03:391267 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071268 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521269
1270 const char* kExpectedResponseData[] = {
1271 "hello", "world"
1272 };
1273
[email protected]58e32bb2013-01-21 18:23:251274 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521275 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411276 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521277
[email protected]262eec82013-03-19 21:01:361278 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521280
[email protected]49639fa2011-12-20 23:22:411281 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421282 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521283
1284 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421285 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521286
[email protected]58e32bb2013-01-21 18:23:251287 LoadTimingInfo load_timing_info;
1288 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1289 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1290 if (i == 0) {
1291 first_socket_log_id = load_timing_info.socket_log_id;
1292 } else {
1293 // The second request should be using a new socket.
1294 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1295 }
1296
[email protected]1c773ea12009-04-28 19:58:421297 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501298 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521299
[email protected]90499482013-06-01 00:39:501300 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251301 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521302
1303 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571304 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421305 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251306 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521307 }
1308}
[email protected]3d2a59b2008-09-26 19:44:251309
[email protected]a34f61ee2014-03-18 20:59:491310void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1311 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101312 const MockRead* read_failure,
1313 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491314 HttpRequestInfo request;
1315 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101316 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491317 request.load_flags = 0;
1318
1319 CapturingNetLog net_log;
1320 session_deps_.net_log = &net_log;
1321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1322
[email protected]09356c652014-03-25 15:36:101323 SSLSocketDataProvider ssl1(ASYNC, OK);
1324 SSLSocketDataProvider ssl2(ASYNC, OK);
1325 if (use_spdy) {
1326 ssl1.SetNextProto(GetParam());
1327 ssl2.SetNextProto(GetParam());
1328 }
1329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491331
[email protected]09356c652014-03-25 15:36:101332 // SPDY versions of the request and response.
1333 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1334 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1335 scoped_ptr<SpdyFrame> spdy_response(
1336 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1337 scoped_ptr<SpdyFrame> spdy_data(
1338 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491339
[email protected]09356c652014-03-25 15:36:101340 // HTTP/1.1 versions of the request and response.
1341 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1342 "Host: www.foo.com\r\n"
1343 "Connection: keep-alive\r\n\r\n";
1344 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1345 const char kHttpData[] = "hello";
1346
1347 std::vector<MockRead> data1_reads;
1348 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491349 if (write_failure) {
1350 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101351 data1_writes.push_back(*write_failure);
1352 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491353 } else {
1354 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101355 if (use_spdy) {
1356 data1_writes.push_back(CreateMockWrite(*spdy_request));
1357 } else {
1358 data1_writes.push_back(MockWrite(kHttpRequest));
1359 }
1360 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491361 }
1362
[email protected]09356c652014-03-25 15:36:101363 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1364 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491365 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1366
[email protected]09356c652014-03-25 15:36:101367 std::vector<MockRead> data2_reads;
1368 std::vector<MockWrite> data2_writes;
1369
1370 if (use_spdy) {
1371 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1372
1373 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1374 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1375 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1376 } else {
1377 data2_writes.push_back(
1378 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1379
1380 data2_reads.push_back(
1381 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1382 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1383 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1384 }
1385 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1386 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491387 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1388
1389 // Preconnect a socket.
1390 net::SSLConfig ssl_config;
1391 session->ssl_config_service()->GetSSLConfig(&ssl_config);
1392 if (session->http_stream_factory()->has_next_protos())
1393 ssl_config.next_protos = session->http_stream_factory()->next_protos();
1394 session->http_stream_factory()->PreconnectStreams(
1395 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1396 // Wait for the preconnect to complete.
1397 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1398 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101399 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491400
1401 // Make the request.
1402 TestCompletionCallback callback;
1403
1404 scoped_ptr<HttpTransaction> trans(
1405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1406
1407 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1408 EXPECT_EQ(ERR_IO_PENDING, rv);
1409
1410 rv = callback.WaitForResult();
1411 EXPECT_EQ(OK, rv);
1412
1413 LoadTimingInfo load_timing_info;
1414 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101415 TestLoadTimingNotReused(
1416 load_timing_info,
1417 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491418
1419 const HttpResponseInfo* response = trans->GetResponseInfo();
1420 ASSERT_TRUE(response != NULL);
1421
1422 EXPECT_TRUE(response->headers.get() != NULL);
1423 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1424
1425 std::string response_data;
1426 rv = ReadTransaction(trans.get(), &response_data);
1427 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101428 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491429}
1430
[email protected]23e482282013-06-14 16:08:021431TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231432 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061433 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511434 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1435}
1436
[email protected]23e482282013-06-14 16:08:021437TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061438 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511439 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251440}
1441
[email protected]23e482282013-06-14 16:08:021442TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061443 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511444 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251445}
1446
[email protected]a34f61ee2014-03-18 20:59:491447TEST_P(HttpNetworkTransactionTest,
1448 PreconnectErrorNotConnectedOnWrite) {
1449 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101450 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491451}
1452
1453TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1454 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101455 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491456}
1457
1458TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1459 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101460 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1461}
1462
1463TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1464 MockRead read_failure(ASYNC, OK); // EOF
1465 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1466}
1467
1468TEST_P(HttpNetworkTransactionTest,
1469 SpdyPreconnectErrorNotConnectedOnWrite) {
1470 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1471 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1472}
1473
1474TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1475 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1476 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1477}
1478
1479TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1480 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1481 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1482}
1483
1484TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1485 MockRead read_failure(ASYNC, OK); // EOF
1486 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491487}
1488
[email protected]23e482282013-06-14 16:08:021489TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421490 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251491 request.method = "GET";
1492 request.url = GURL("http://www.google.com/");
1493 request.load_flags = 0;
1494
[email protected]3fe8d2f82013-10-17 08:56:071495 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271496 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071497 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271498
[email protected]3d2a59b2008-09-26 19:44:251499 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061500 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351501 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1502 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061503 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251504 };
[email protected]31a2bfe2010-02-09 08:03:391505 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071506 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251507
[email protected]49639fa2011-12-20 23:22:411508 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251509
[email protected]49639fa2011-12-20 23:22:411510 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421511 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251512
1513 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421514 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251515
[email protected]1c773ea12009-04-28 19:58:421516 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251517 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251518}
1519
1520// What do various browsers do when the server closes a non-keepalive
1521// connection without sending any response header or body?
1522//
1523// IE7: error page
1524// Safari 3.1.2 (Windows): error page
1525// Firefox 3.0.1: blank page
1526// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421527// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1528// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021529TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251530 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061531 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351532 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1533 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061534 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251535 };
[email protected]31a2bfe2010-02-09 08:03:391536 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1537 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421538 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251539}
[email protected]038e9a32008-10-08 22:40:161540
[email protected]1826a402014-01-08 15:40:481541// Test that network access can be deferred and resumed.
1542TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1543 HttpRequestInfo request;
1544 request.method = "GET";
1545 request.url = GURL("http://www.google.com/");
1546 request.load_flags = 0;
1547
1548 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1549 scoped_ptr<HttpTransaction> trans(
1550 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1551
1552 // Defer on OnBeforeNetworkStart.
1553 BeforeNetworkStartHandler net_start_handler(true); // defer
1554 trans->SetBeforeNetworkStartCallback(
1555 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1556 base::Unretained(&net_start_handler)));
1557
1558 MockRead data_reads[] = {
1559 MockRead("HTTP/1.0 200 OK\r\n"),
1560 MockRead("Content-Length: 5\r\n\r\n"),
1561 MockRead("hello"),
1562 MockRead(SYNCHRONOUS, 0),
1563 };
1564 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1565 session_deps_.socket_factory->AddSocketDataProvider(&data);
1566
1567 TestCompletionCallback callback;
1568
1569 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1570 EXPECT_EQ(ERR_IO_PENDING, rv);
1571 base::MessageLoop::current()->RunUntilIdle();
1572
1573 // Should have deferred for network start.
1574 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1575 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1576 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1577
1578 trans->ResumeNetworkStart();
1579 rv = callback.WaitForResult();
1580 EXPECT_EQ(OK, rv);
1581 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1582
1583 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1584 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1585 if (rv == ERR_IO_PENDING)
1586 rv = callback.WaitForResult();
1587 EXPECT_EQ(5, rv);
1588 trans.reset();
1589}
1590
1591// Test that network use can be deferred and canceled.
1592TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1593 HttpRequestInfo request;
1594 request.method = "GET";
1595 request.url = GURL("http://www.google.com/");
1596 request.load_flags = 0;
1597
1598 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1599 scoped_ptr<HttpTransaction> trans(
1600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1601
1602 // Defer on OnBeforeNetworkStart.
1603 BeforeNetworkStartHandler net_start_handler(true); // defer
1604 trans->SetBeforeNetworkStartCallback(
1605 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1606 base::Unretained(&net_start_handler)));
1607
1608 TestCompletionCallback callback;
1609
1610 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1611 EXPECT_EQ(ERR_IO_PENDING, rv);
1612 base::MessageLoop::current()->RunUntilIdle();
1613
1614 // Should have deferred for network start.
1615 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1616 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1617 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1618}
1619
[email protected]7a5378b2012-11-04 03:25:171620// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1621// tests. There was a bug causing HttpNetworkTransaction to hang in the
1622// destructor in such situations.
1623// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021624TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171625 HttpRequestInfo request;
1626 request.method = "GET";
1627 request.url = GURL("http://www.google.com/");
1628 request.load_flags = 0;
1629
[email protected]bb88e1d32013-05-03 23:11:071630 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361631 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501632 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171633
1634 MockRead data_reads[] = {
1635 MockRead("HTTP/1.0 200 OK\r\n"),
1636 MockRead("Connection: keep-alive\r\n"),
1637 MockRead("Content-Length: 100\r\n\r\n"),
1638 MockRead("hello"),
1639 MockRead(SYNCHRONOUS, 0),
1640 };
1641 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071642 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171643
1644 TestCompletionCallback callback;
1645
1646 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1647 EXPECT_EQ(ERR_IO_PENDING, rv);
1648
1649 rv = callback.WaitForResult();
1650 EXPECT_EQ(OK, rv);
1651
1652 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501653 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171654 if (rv == ERR_IO_PENDING)
1655 rv = callback.WaitForResult();
1656 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501657 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171658 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1659
1660 trans.reset();
[email protected]2da659e2013-05-23 20:51:341661 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171662 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1663}
1664
[email protected]23e482282013-06-14 16:08:021665TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171666 HttpRequestInfo request;
1667 request.method = "GET";
1668 request.url = GURL("http://www.google.com/");
1669 request.load_flags = 0;
1670
[email protected]bb88e1d32013-05-03 23:11:071671 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361672 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501673 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171674
1675 MockRead data_reads[] = {
1676 MockRead("HTTP/1.0 200 OK\r\n"),
1677 MockRead("Connection: keep-alive\r\n"),
1678 MockRead("Content-Length: 100\r\n\r\n"),
1679 MockRead(SYNCHRONOUS, 0),
1680 };
1681 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071682 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171683
1684 TestCompletionCallback callback;
1685
1686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1687 EXPECT_EQ(ERR_IO_PENDING, rv);
1688
1689 rv = callback.WaitForResult();
1690 EXPECT_EQ(OK, rv);
1691
1692 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501693 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171694 if (rv == ERR_IO_PENDING)
1695 rv = callback.WaitForResult();
1696 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1697
1698 trans.reset();
[email protected]2da659e2013-05-23 20:51:341699 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171700 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1701}
1702
[email protected]0b0bf032010-09-21 18:08:501703// Test that we correctly reuse a keep-alive connection after not explicitly
1704// reading the body.
[email protected]23e482282013-06-14 16:08:021705TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131706 HttpRequestInfo request;
1707 request.method = "GET";
1708 request.url = GURL("http://www.foo.com/");
1709 request.load_flags = 0;
1710
[email protected]58e32bb2013-01-21 18:23:251711 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071712 session_deps_.net_log = &net_log;
1713 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271714
[email protected]0b0bf032010-09-21 18:08:501715 // Note that because all these reads happen in the same
1716 // StaticSocketDataProvider, it shows that the same socket is being reused for
1717 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131718 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501719 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1720 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131721 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501722 MockRead("HTTP/1.1 302 Found\r\n"
1723 "Content-Length: 0\r\n\r\n"),
1724 MockRead("HTTP/1.1 302 Found\r\n"
1725 "Content-Length: 5\r\n\r\n"
1726 "hello"),
1727 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1728 "Content-Length: 0\r\n\r\n"),
1729 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1730 "Content-Length: 5\r\n\r\n"
1731 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131732 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1733 MockRead("hello"),
1734 };
1735 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131737
1738 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061739 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131740 };
1741 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071742 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131743
[email protected]0b0bf032010-09-21 18:08:501744 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1745 std::string response_lines[kNumUnreadBodies];
1746
[email protected]58e32bb2013-01-21 18:23:251747 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501748 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411749 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131750
[email protected]262eec82013-03-19 21:01:361751 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501752 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131753
[email protected]49639fa2011-12-20 23:22:411754 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131755 EXPECT_EQ(ERR_IO_PENDING, rv);
1756
1757 rv = callback.WaitForResult();
1758 EXPECT_EQ(OK, rv);
1759
[email protected]58e32bb2013-01-21 18:23:251760 LoadTimingInfo load_timing_info;
1761 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1762 if (i == 0) {
1763 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1764 first_socket_log_id = load_timing_info.socket_log_id;
1765 } else {
1766 TestLoadTimingReused(load_timing_info);
1767 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1768 }
1769
[email protected]fc31d6a42010-06-24 18:05:131770 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501771 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131772
[email protected]90499482013-06-01 00:39:501773 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501774 response_lines[i] = response->headers->GetStatusLine();
1775
1776 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131777 }
[email protected]0b0bf032010-09-21 18:08:501778
1779 const char* const kStatusLines[] = {
1780 "HTTP/1.1 204 No Content",
1781 "HTTP/1.1 205 Reset Content",
1782 "HTTP/1.1 304 Not Modified",
1783 "HTTP/1.1 302 Found",
1784 "HTTP/1.1 302 Found",
1785 "HTTP/1.1 301 Moved Permanently",
1786 "HTTP/1.1 301 Moved Permanently",
1787 };
1788
1789 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1790 forgot_to_update_kStatusLines);
1791
1792 for (int i = 0; i < kNumUnreadBodies; ++i)
1793 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1794
[email protected]49639fa2011-12-20 23:22:411795 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361796 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501797 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411798 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501799 EXPECT_EQ(ERR_IO_PENDING, rv);
1800 rv = callback.WaitForResult();
1801 EXPECT_EQ(OK, rv);
1802 const HttpResponseInfo* response = trans->GetResponseInfo();
1803 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501804 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501805 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1806 std::string response_data;
1807 rv = ReadTransaction(trans.get(), &response_data);
1808 EXPECT_EQ(OK, rv);
1809 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131810}
1811
[email protected]038e9a32008-10-08 22:40:161812// Test the request-challenge-retry sequence for basic auth.
1813// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021814TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421815 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161816 request.method = "GET";
1817 request.url = GURL("http://www.google.com/");
1818 request.load_flags = 0;
1819
[email protected]58e32bb2013-01-21 18:23:251820 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071821 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071822 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271823 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071824 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271825
[email protected]f9ee6b52008-11-08 06:46:231826 MockWrite data_writes1[] = {
1827 MockWrite("GET / HTTP/1.1\r\n"
1828 "Host: www.google.com\r\n"
1829 "Connection: keep-alive\r\n\r\n"),
1830 };
1831
[email protected]038e9a32008-10-08 22:40:161832 MockRead data_reads1[] = {
1833 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1834 // Give a couple authenticate options (only the middle one is actually
1835 // supported).
[email protected]22927ad2009-09-21 19:56:191836 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161837 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1838 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1840 // Large content-length -- won't matter, as connection will be reset.
1841 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061842 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161843 };
1844
1845 // After calling trans->RestartWithAuth(), this is the request we should
1846 // be issuing -- the final header line contains the credentials.
1847 MockWrite data_writes2[] = {
1848 MockWrite("GET / HTTP/1.1\r\n"
1849 "Host: www.google.com\r\n"
1850 "Connection: keep-alive\r\n"
1851 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1852 };
1853
1854 // Lastly, the server responds with the actual content.
1855 MockRead data_reads2[] = {
1856 MockRead("HTTP/1.0 200 OK\r\n"),
1857 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1858 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061859 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161860 };
1861
[email protected]31a2bfe2010-02-09 08:03:391862 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1863 data_writes1, arraysize(data_writes1));
1864 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1865 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071866 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1867 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161868
[email protected]49639fa2011-12-20 23:22:411869 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161870
[email protected]49639fa2011-12-20 23:22:411871 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421872 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161873
1874 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421875 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161876
[email protected]58e32bb2013-01-21 18:23:251877 LoadTimingInfo load_timing_info1;
1878 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1879 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1880
[email protected]b8015c42013-12-24 15:18:191881 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1882 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1883
[email protected]1c773ea12009-04-28 19:58:421884 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501885 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041886 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161887
[email protected]49639fa2011-12-20 23:22:411888 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161889
[email protected]49639fa2011-12-20 23:22:411890 rv = trans->RestartWithAuth(
1891 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421892 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161893
1894 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421895 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161896
[email protected]58e32bb2013-01-21 18:23:251897 LoadTimingInfo load_timing_info2;
1898 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1899 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1900 // The load timing after restart should have a new socket ID, and times after
1901 // those of the first load timing.
1902 EXPECT_LE(load_timing_info1.receive_headers_end,
1903 load_timing_info2.connect_timing.connect_start);
1904 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1905
[email protected]b8015c42013-12-24 15:18:191906 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1907 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1908
[email protected]038e9a32008-10-08 22:40:161909 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501910 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161911 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1912 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161913}
1914
[email protected]23e482282013-06-14 16:08:021915TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461916 HttpRequestInfo request;
1917 request.method = "GET";
1918 request.url = GURL("http://www.google.com/");
1919 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1920
[email protected]3fe8d2f82013-10-17 08:56:071921 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271922 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271924
[email protected]861fcd52009-08-26 02:33:461925 MockWrite data_writes[] = {
1926 MockWrite("GET / HTTP/1.1\r\n"
1927 "Host: www.google.com\r\n"
1928 "Connection: keep-alive\r\n\r\n"),
1929 };
1930
1931 MockRead data_reads[] = {
1932 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1933 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1934 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1935 // Large content-length -- won't matter, as connection will be reset.
1936 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061937 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461938 };
1939
[email protected]31a2bfe2010-02-09 08:03:391940 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1941 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071942 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411943 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461944
[email protected]49639fa2011-12-20 23:22:411945 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461946 EXPECT_EQ(ERR_IO_PENDING, rv);
1947
1948 rv = callback.WaitForResult();
1949 EXPECT_EQ(0, rv);
1950
[email protected]b8015c42013-12-24 15:18:191951 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
1952 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
1953
[email protected]861fcd52009-08-26 02:33:461954 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501955 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461956 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1957}
1958
[email protected]2d2697f92009-02-18 21:00:321959// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1960// connection.
[email protected]23e482282013-06-14 16:08:021961TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421962 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321963 request.method = "GET";
1964 request.url = GURL("http://www.google.com/");
1965 request.load_flags = 0;
1966
[email protected]58e32bb2013-01-21 18:23:251967 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071968 session_deps_.net_log = &log;
1969 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271970
[email protected]2d2697f92009-02-18 21:00:321971 MockWrite data_writes1[] = {
1972 MockWrite("GET / HTTP/1.1\r\n"
1973 "Host: www.google.com\r\n"
1974 "Connection: keep-alive\r\n\r\n"),
1975
1976 // After calling trans->RestartWithAuth(), this is the request we should
1977 // be issuing -- the final header line contains the credentials.
1978 MockWrite("GET / HTTP/1.1\r\n"
1979 "Host: www.google.com\r\n"
1980 "Connection: keep-alive\r\n"
1981 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1982 };
1983
1984 MockRead data_reads1[] = {
1985 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1986 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1987 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1988 MockRead("Content-Length: 14\r\n\r\n"),
1989 MockRead("Unauthorized\r\n"),
1990
1991 // Lastly, the server responds with the actual content.
1992 MockRead("HTTP/1.1 200 OK\r\n"),
1993 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501994 MockRead("Content-Length: 5\r\n\r\n"),
1995 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321996 };
1997
[email protected]2d0a4f92011-05-05 16:38:461998 // If there is a regression where we disconnect a Keep-Alive
1999 // connection during an auth roundtrip, we'll end up reading this.
2000 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062001 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462002 };
2003
[email protected]31a2bfe2010-02-09 08:03:392004 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2005 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462006 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2007 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072008 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2009 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322010
[email protected]49639fa2011-12-20 23:22:412011 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322012
[email protected]262eec82013-03-19 21:01:362013 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412015 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422016 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322017
2018 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422019 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322020
[email protected]58e32bb2013-01-21 18:23:252021 LoadTimingInfo load_timing_info1;
2022 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2023 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2024
[email protected]1c773ea12009-04-28 19:58:422025 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502026 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042027 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322028
[email protected]49639fa2011-12-20 23:22:412029 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322030
[email protected]49639fa2011-12-20 23:22:412031 rv = trans->RestartWithAuth(
2032 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322034
2035 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422036 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322037
[email protected]58e32bb2013-01-21 18:23:252038 LoadTimingInfo load_timing_info2;
2039 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2040 TestLoadTimingReused(load_timing_info2);
2041 // The load timing after restart should have the same socket ID, and times
2042 // those of the first load timing.
2043 EXPECT_LE(load_timing_info1.receive_headers_end,
2044 load_timing_info2.send_start);
2045 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2046
[email protected]2d2697f92009-02-18 21:00:322047 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502048 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322049 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502050 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192051
2052 std::string response_data;
2053 rv = ReadTransaction(trans.get(), &response_data);
2054 EXPECT_EQ(OK, rv);
2055 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2056 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322057}
2058
2059// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2060// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022061TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422062 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322063 request.method = "GET";
2064 request.url = GURL("http://www.google.com/");
2065 request.load_flags = 0;
2066
[email protected]bb88e1d32013-05-03 23:11:072067 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272068
[email protected]2d2697f92009-02-18 21:00:322069 MockWrite data_writes1[] = {
2070 MockWrite("GET / HTTP/1.1\r\n"
2071 "Host: www.google.com\r\n"
2072 "Connection: keep-alive\r\n\r\n"),
2073
2074 // After calling trans->RestartWithAuth(), this is the request we should
2075 // be issuing -- the final header line contains the credentials.
2076 MockWrite("GET / HTTP/1.1\r\n"
2077 "Host: www.google.com\r\n"
2078 "Connection: keep-alive\r\n"
2079 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2080 };
2081
[email protected]2d2697f92009-02-18 21:00:322082 MockRead data_reads1[] = {
2083 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2084 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312085 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322086
2087 // Lastly, the server responds with the actual content.
2088 MockRead("HTTP/1.1 200 OK\r\n"),
2089 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502090 MockRead("Content-Length: 5\r\n\r\n"),
2091 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322092 };
2093
[email protected]2d0a4f92011-05-05 16:38:462094 // An incorrect reconnect would cause this to be read.
2095 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062096 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462097 };
2098
[email protected]31a2bfe2010-02-09 08:03:392099 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2100 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462101 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2102 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072103 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2104 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322105
[email protected]49639fa2011-12-20 23:22:412106 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322107
[email protected]262eec82013-03-19 21:01:362108 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412110 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422111 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322112
2113 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422114 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322115
[email protected]1c773ea12009-04-28 19:58:422116 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502117 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042118 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322119
[email protected]49639fa2011-12-20 23:22:412120 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322121
[email protected]49639fa2011-12-20 23:22:412122 rv = trans->RestartWithAuth(
2123 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422124 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322125
2126 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422127 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322128
2129 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502130 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322131 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502132 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322133}
2134
2135// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2136// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022137TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422138 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322139 request.method = "GET";
2140 request.url = GURL("http://www.google.com/");
2141 request.load_flags = 0;
2142
[email protected]bb88e1d32013-05-03 23:11:072143 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272144
[email protected]2d2697f92009-02-18 21:00:322145 MockWrite data_writes1[] = {
2146 MockWrite("GET / HTTP/1.1\r\n"
2147 "Host: www.google.com\r\n"
2148 "Connection: keep-alive\r\n\r\n"),
2149
2150 // After calling trans->RestartWithAuth(), this is the request we should
2151 // be issuing -- the final header line contains the credentials.
2152 MockWrite("GET / HTTP/1.1\r\n"
2153 "Host: www.google.com\r\n"
2154 "Connection: keep-alive\r\n"
2155 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2156 };
2157
2158 // Respond with 5 kb of response body.
2159 std::string large_body_string("Unauthorized");
2160 large_body_string.append(5 * 1024, ' ');
2161 large_body_string.append("\r\n");
2162
2163 MockRead data_reads1[] = {
2164 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2165 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2166 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2167 // 5134 = 12 + 5 * 1024 + 2
2168 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062169 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322170
2171 // Lastly, the server responds with the actual content.
2172 MockRead("HTTP/1.1 200 OK\r\n"),
2173 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502174 MockRead("Content-Length: 5\r\n\r\n"),
2175 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322176 };
2177
[email protected]2d0a4f92011-05-05 16:38:462178 // An incorrect reconnect would cause this to be read.
2179 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062180 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462181 };
2182
[email protected]31a2bfe2010-02-09 08:03:392183 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2184 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462185 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2186 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072187 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2188 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322189
[email protected]49639fa2011-12-20 23:22:412190 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322191
[email protected]262eec82013-03-19 21:01:362192 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412194 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422195 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322196
2197 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422198 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322199
[email protected]1c773ea12009-04-28 19:58:422200 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502201 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042202 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322203
[email protected]49639fa2011-12-20 23:22:412204 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322205
[email protected]49639fa2011-12-20 23:22:412206 rv = trans->RestartWithAuth(
2207 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422208 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322209
2210 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422211 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322212
2213 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502214 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322215 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502216 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322217}
2218
2219// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312220// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022221TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312222 HttpRequestInfo request;
2223 request.method = "GET";
2224 request.url = GURL("http://www.google.com/");
2225 request.load_flags = 0;
2226
[email protected]bb88e1d32013-05-03 23:11:072227 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272228
[email protected]11203f012009-11-12 23:02:312229 MockWrite data_writes1[] = {
2230 MockWrite("GET / HTTP/1.1\r\n"
2231 "Host: www.google.com\r\n"
2232 "Connection: keep-alive\r\n\r\n"),
2233 // This simulates the seemingly successful write to a closed connection
2234 // if the bug is not fixed.
2235 MockWrite("GET / HTTP/1.1\r\n"
2236 "Host: www.google.com\r\n"
2237 "Connection: keep-alive\r\n"
2238 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2239 };
2240
2241 MockRead data_reads1[] = {
2242 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2243 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2244 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2245 MockRead("Content-Length: 14\r\n\r\n"),
2246 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062247 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312248 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062249 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312250 };
2251
2252 // After calling trans->RestartWithAuth(), this is the request we should
2253 // be issuing -- the final header line contains the credentials.
2254 MockWrite data_writes2[] = {
2255 MockWrite("GET / HTTP/1.1\r\n"
2256 "Host: www.google.com\r\n"
2257 "Connection: keep-alive\r\n"
2258 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2259 };
2260
2261 // Lastly, the server responds with the actual content.
2262 MockRead data_reads2[] = {
2263 MockRead("HTTP/1.1 200 OK\r\n"),
2264 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502265 MockRead("Content-Length: 5\r\n\r\n"),
2266 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312267 };
2268
[email protected]31a2bfe2010-02-09 08:03:392269 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2270 data_writes1, arraysize(data_writes1));
2271 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2272 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072273 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2274 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312275
[email protected]49639fa2011-12-20 23:22:412276 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312277
[email protected]262eec82013-03-19 21:01:362278 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412280 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312281 EXPECT_EQ(ERR_IO_PENDING, rv);
2282
2283 rv = callback1.WaitForResult();
2284 EXPECT_EQ(OK, rv);
2285
2286 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502287 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042288 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312289
[email protected]49639fa2011-12-20 23:22:412290 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312291
[email protected]49639fa2011-12-20 23:22:412292 rv = trans->RestartWithAuth(
2293 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312294 EXPECT_EQ(ERR_IO_PENDING, rv);
2295
2296 rv = callback2.WaitForResult();
2297 EXPECT_EQ(OK, rv);
2298
2299 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502300 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312301 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502302 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312303}
2304
[email protected]394816e92010-08-03 07:38:592305// Test the request-challenge-retry sequence for basic auth, over a connection
2306// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022307TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592308 HttpRequestInfo request;
2309 request.method = "GET";
2310 request.url = GURL("https://www.google.com/");
2311 // when the no authentication data flag is set.
2312 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2313
[email protected]cb9bf6ca2011-01-28 13:15:272314 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072315 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202316 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292317 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072318 session_deps_.net_log = log.bound().net_log();
2319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272320
[email protected]394816e92010-08-03 07:38:592321 // Since we have proxy, should try to establish tunnel.
2322 MockWrite data_writes1[] = {
2323 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2324 "Host: www.google.com\r\n"
2325 "Proxy-Connection: keep-alive\r\n\r\n"),
2326
2327 // After calling trans->RestartWithAuth(), this is the request we should
2328 // be issuing -- the final header line contains the credentials.
2329 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2330 "Host: www.google.com\r\n"
2331 "Proxy-Connection: keep-alive\r\n"
2332 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2333
2334 MockWrite("GET / HTTP/1.1\r\n"
2335 "Host: www.google.com\r\n"
2336 "Connection: keep-alive\r\n\r\n"),
2337 };
2338
2339 // The proxy responds to the connect with a 407, using a persistent
2340 // connection.
2341 MockRead data_reads1[] = {
2342 // No credentials.
2343 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2344 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2345 MockRead("Proxy-Connection: close\r\n\r\n"),
2346
2347 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2348
2349 MockRead("HTTP/1.1 200 OK\r\n"),
2350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502351 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062352 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592353 };
2354
2355 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2356 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072357 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062358 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592360
[email protected]49639fa2011-12-20 23:22:412361 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592362
[email protected]262eec82013-03-19 21:01:362363 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502365
[email protected]49639fa2011-12-20 23:22:412366 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592367 EXPECT_EQ(ERR_IO_PENDING, rv);
2368
2369 rv = callback1.WaitForResult();
2370 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572371 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402372 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592373 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402374 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592375 NetLog::PHASE_NONE);
2376 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402377 entries, pos,
[email protected]394816e92010-08-03 07:38:592378 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2379 NetLog::PHASE_NONE);
2380
2381 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502382 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502383 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592384 EXPECT_EQ(407, response->headers->response_code());
2385 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042386 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592387
[email protected]029c83b62013-01-24 05:28:202388 LoadTimingInfo load_timing_info;
2389 // CONNECT requests and responses are handled at the connect job level, so
2390 // the transaction does not yet have a connection.
2391 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2392
[email protected]49639fa2011-12-20 23:22:412393 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592394
[email protected]49639fa2011-12-20 23:22:412395 rv = trans->RestartWithAuth(
2396 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592397 EXPECT_EQ(ERR_IO_PENDING, rv);
2398
2399 rv = callback2.WaitForResult();
2400 EXPECT_EQ(OK, rv);
2401
2402 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502403 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592404
2405 EXPECT_TRUE(response->headers->IsKeepAlive());
2406 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502407 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592408 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2409
2410 // The password prompt info should not be set.
2411 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502412
[email protected]029c83b62013-01-24 05:28:202413 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2414 TestLoadTimingNotReusedWithPac(load_timing_info,
2415 CONNECT_TIMING_HAS_SSL_TIMES);
2416
[email protected]0b0bf032010-09-21 18:08:502417 trans.reset();
[email protected]102e27c2011-02-23 01:01:312418 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592419}
2420
[email protected]11203f012009-11-12 23:02:312421// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322422// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022423TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272424 HttpRequestInfo request;
2425 request.method = "GET";
2426 request.url = GURL("https://www.google.com/");
2427 // Ensure that proxy authentication is attempted even
2428 // when the no authentication data flag is set.
2429 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2430
[email protected]2d2697f92009-02-18 21:00:322431 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072432 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292433 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072434 session_deps_.net_log = log.bound().net_log();
2435 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322436
[email protected]262eec82013-03-19 21:01:362437 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502438 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322439
[email protected]2d2697f92009-02-18 21:00:322440 // Since we have proxy, should try to establish tunnel.
2441 MockWrite data_writes1[] = {
2442 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452443 "Host: www.google.com\r\n"
2444 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322445
2446 // After calling trans->RestartWithAuth(), this is the request we should
2447 // be issuing -- the final header line contains the credentials.
2448 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2449 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452450 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322451 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2452 };
2453
2454 // The proxy responds to the connect with a 407, using a persistent
2455 // connection.
2456 MockRead data_reads1[] = {
2457 // No credentials.
2458 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2459 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2460 MockRead("Content-Length: 10\r\n\r\n"),
2461 MockRead("0123456789"),
2462
2463 // Wrong credentials (wrong password).
2464 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2465 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2466 MockRead("Content-Length: 10\r\n\r\n"),
2467 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062468 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322469 };
2470
[email protected]31a2bfe2010-02-09 08:03:392471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2472 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322474
[email protected]49639fa2011-12-20 23:22:412475 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322476
[email protected]49639fa2011-12-20 23:22:412477 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422478 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322479
2480 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422481 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572482 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402483 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392484 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402485 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392486 NetLog::PHASE_NONE);
2487 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402488 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392489 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2490 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322491
[email protected]1c773ea12009-04-28 19:58:422492 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502493 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502494 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322495 EXPECT_TRUE(response->headers->IsKeepAlive());
2496 EXPECT_EQ(407, response->headers->response_code());
2497 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422498 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042499 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322500
[email protected]49639fa2011-12-20 23:22:412501 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322502
2503 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412504 rv = trans->RestartWithAuth(
2505 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422506 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322507
2508 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422509 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322510
2511 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502512 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502513 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322514 EXPECT_TRUE(response->headers->IsKeepAlive());
2515 EXPECT_EQ(407, response->headers->response_code());
2516 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422517 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042518 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132519
[email protected]e60e47a2010-07-14 03:37:182520 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2521 // out of scope.
[email protected]102e27c2011-02-23 01:01:312522 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322523}
2524
[email protected]a8e9b162009-03-12 00:06:442525// Test that we don't read the response body when we fail to establish a tunnel,
2526// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022527TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272528 HttpRequestInfo request;
2529 request.method = "GET";
2530 request.url = GURL("https://www.google.com/");
2531 request.load_flags = 0;
2532
[email protected]a8e9b162009-03-12 00:06:442533 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072534 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442535
[email protected]bb88e1d32013-05-03 23:11:072536 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442537
[email protected]262eec82013-03-19 21:01:362538 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442540
[email protected]a8e9b162009-03-12 00:06:442541 // Since we have proxy, should try to establish tunnel.
2542 MockWrite data_writes[] = {
2543 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452544 "Host: www.google.com\r\n"
2545 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442546 };
2547
2548 // The proxy responds to the connect with a 407.
2549 MockRead data_reads[] = {
2550 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2551 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2552 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062553 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442554 };
2555
[email protected]31a2bfe2010-02-09 08:03:392556 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2557 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072558 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442559
[email protected]49639fa2011-12-20 23:22:412560 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442561
[email protected]49639fa2011-12-20 23:22:412562 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422563 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442564
2565 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422566 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442567
[email protected]1c773ea12009-04-28 19:58:422568 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502569 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442570
2571 EXPECT_TRUE(response->headers->IsKeepAlive());
2572 EXPECT_EQ(407, response->headers->response_code());
2573 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422574 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442575
2576 std::string response_data;
2577 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422578 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182579
2580 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312581 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442582}
2583
[email protected]8fdbcd22010-05-05 02:54:522584// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2585// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022586TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522587 HttpRequestInfo request;
2588 request.method = "GET";
2589 request.url = GURL("http://www.google.com/");
2590 request.load_flags = 0;
2591
[email protected]cb9bf6ca2011-01-28 13:15:272592 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072593 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272594 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272596
[email protected]8fdbcd22010-05-05 02:54:522597 MockWrite data_writes1[] = {
2598 MockWrite("GET / HTTP/1.1\r\n"
2599 "Host: www.google.com\r\n"
2600 "Connection: keep-alive\r\n\r\n"),
2601 };
2602
2603 MockRead data_reads1[] = {
2604 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2605 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2606 // Large content-length -- won't matter, as connection will be reset.
2607 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062608 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522609 };
2610
2611 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2612 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072613 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522614
[email protected]49639fa2011-12-20 23:22:412615 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522616
[email protected]49639fa2011-12-20 23:22:412617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522618 EXPECT_EQ(ERR_IO_PENDING, rv);
2619
2620 rv = callback.WaitForResult();
2621 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2622}
2623
[email protected]7a67a8152010-11-05 18:31:102624// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2625// through a non-authenticating proxy. The request should fail with
2626// ERR_UNEXPECTED_PROXY_AUTH.
2627// Note that it is impossible to detect if an HTTP server returns a 407 through
2628// a non-authenticating proxy - there is nothing to indicate whether the
2629// response came from the proxy or the server, so it is treated as if the proxy
2630// issued the challenge.
[email protected]23e482282013-06-14 16:08:022631TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232632 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272633 HttpRequestInfo request;
2634 request.method = "GET";
2635 request.url = GURL("https://www.google.com/");
2636
[email protected]bb88e1d32013-05-03 23:11:072637 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292638 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072639 session_deps_.net_log = log.bound().net_log();
2640 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102641
[email protected]7a67a8152010-11-05 18:31:102642 // Since we have proxy, should try to establish tunnel.
2643 MockWrite data_writes1[] = {
2644 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2645 "Host: www.google.com\r\n"
2646 "Proxy-Connection: keep-alive\r\n\r\n"),
2647
2648 MockWrite("GET / HTTP/1.1\r\n"
2649 "Host: www.google.com\r\n"
2650 "Connection: keep-alive\r\n\r\n"),
2651 };
2652
2653 MockRead data_reads1[] = {
2654 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2655
2656 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2657 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2658 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062659 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102660 };
2661
2662 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2663 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062665 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102667
[email protected]49639fa2011-12-20 23:22:412668 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102669
[email protected]262eec82013-03-19 21:01:362670 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502671 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102672
[email protected]49639fa2011-12-20 23:22:412673 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102674 EXPECT_EQ(ERR_IO_PENDING, rv);
2675
2676 rv = callback1.WaitForResult();
2677 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572678 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402679 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102680 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402681 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102682 NetLog::PHASE_NONE);
2683 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402684 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102685 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2686 NetLog::PHASE_NONE);
2687}
[email protected]2df19bb2010-08-25 20:13:462688
[email protected]029c83b62013-01-24 05:28:202689// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022690TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202691 HttpRequestInfo request1;
2692 request1.method = "GET";
2693 request1.url = GURL("https://www.google.com/1");
2694
2695 HttpRequestInfo request2;
2696 request2.method = "GET";
2697 request2.url = GURL("https://www.google.com/2");
2698
2699 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072700 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202701 ProxyService::CreateFixed("PROXY myproxy:70"));
2702 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072703 session_deps_.net_log = log.bound().net_log();
2704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202705
2706 // Since we have proxy, should try to establish tunnel.
2707 MockWrite data_writes1[] = {
2708 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2709 "Host: www.google.com\r\n"
2710 "Proxy-Connection: keep-alive\r\n\r\n"),
2711
2712 MockWrite("GET /1 HTTP/1.1\r\n"
2713 "Host: www.google.com\r\n"
2714 "Connection: keep-alive\r\n\r\n"),
2715
2716 MockWrite("GET /2 HTTP/1.1\r\n"
2717 "Host: www.google.com\r\n"
2718 "Connection: keep-alive\r\n\r\n"),
2719 };
2720
2721 // The proxy responds to the connect with a 407, using a persistent
2722 // connection.
2723 MockRead data_reads1[] = {
2724 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2725
2726 MockRead("HTTP/1.1 200 OK\r\n"),
2727 MockRead("Content-Length: 1\r\n\r\n"),
2728 MockRead(SYNCHRONOUS, "1"),
2729
2730 MockRead("HTTP/1.1 200 OK\r\n"),
2731 MockRead("Content-Length: 2\r\n\r\n"),
2732 MockRead(SYNCHRONOUS, "22"),
2733 };
2734
2735 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2736 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072737 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202738 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202740
2741 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362742 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502743 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202744
2745 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2746 EXPECT_EQ(ERR_IO_PENDING, rv);
2747
2748 rv = callback1.WaitForResult();
2749 EXPECT_EQ(OK, rv);
2750
2751 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2752 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502753 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202754 EXPECT_EQ(1, response1->headers->GetContentLength());
2755
2756 LoadTimingInfo load_timing_info1;
2757 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2758 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2759
2760 trans1.reset();
2761
2762 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362763 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202765
2766 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2767 EXPECT_EQ(ERR_IO_PENDING, rv);
2768
2769 rv = callback2.WaitForResult();
2770 EXPECT_EQ(OK, rv);
2771
2772 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2773 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502774 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202775 EXPECT_EQ(2, response2->headers->GetContentLength());
2776
2777 LoadTimingInfo load_timing_info2;
2778 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2779 TestLoadTimingReused(load_timing_info2);
2780
2781 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2782
2783 trans2.reset();
2784 session->CloseAllConnections();
2785}
2786
2787// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022788TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202789 HttpRequestInfo request1;
2790 request1.method = "GET";
2791 request1.url = GURL("https://www.google.com/1");
2792
2793 HttpRequestInfo request2;
2794 request2.method = "GET";
2795 request2.url = GURL("https://www.google.com/2");
2796
2797 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072798 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202799 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2800 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072801 session_deps_.net_log = log.bound().net_log();
2802 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202803
2804 // Since we have proxy, should try to establish tunnel.
2805 MockWrite data_writes1[] = {
2806 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2807 "Host: www.google.com\r\n"
2808 "Proxy-Connection: keep-alive\r\n\r\n"),
2809
2810 MockWrite("GET /1 HTTP/1.1\r\n"
2811 "Host: www.google.com\r\n"
2812 "Connection: keep-alive\r\n\r\n"),
2813
2814 MockWrite("GET /2 HTTP/1.1\r\n"
2815 "Host: www.google.com\r\n"
2816 "Connection: keep-alive\r\n\r\n"),
2817 };
2818
2819 // The proxy responds to the connect with a 407, using a persistent
2820 // connection.
2821 MockRead data_reads1[] = {
2822 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2823
2824 MockRead("HTTP/1.1 200 OK\r\n"),
2825 MockRead("Content-Length: 1\r\n\r\n"),
2826 MockRead(SYNCHRONOUS, "1"),
2827
2828 MockRead("HTTP/1.1 200 OK\r\n"),
2829 MockRead("Content-Length: 2\r\n\r\n"),
2830 MockRead(SYNCHRONOUS, "22"),
2831 };
2832
2833 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2834 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072835 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202836 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202838
2839 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362840 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202842
2843 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2844 EXPECT_EQ(ERR_IO_PENDING, rv);
2845
2846 rv = callback1.WaitForResult();
2847 EXPECT_EQ(OK, rv);
2848
2849 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2850 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502851 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202852 EXPECT_EQ(1, response1->headers->GetContentLength());
2853
2854 LoadTimingInfo load_timing_info1;
2855 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2856 TestLoadTimingNotReusedWithPac(load_timing_info1,
2857 CONNECT_TIMING_HAS_SSL_TIMES);
2858
2859 trans1.reset();
2860
2861 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362862 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202864
2865 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2866 EXPECT_EQ(ERR_IO_PENDING, rv);
2867
2868 rv = callback2.WaitForResult();
2869 EXPECT_EQ(OK, rv);
2870
2871 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2872 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502873 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202874 EXPECT_EQ(2, response2->headers->GetContentLength());
2875
2876 LoadTimingInfo load_timing_info2;
2877 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2878 TestLoadTimingReusedWithPac(load_timing_info2);
2879
2880 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2881
2882 trans2.reset();
2883 session->CloseAllConnections();
2884}
2885
[email protected]2df19bb2010-08-25 20:13:462886// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022887TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272888 HttpRequestInfo request;
2889 request.method = "GET";
2890 request.url = GURL("http://www.google.com/");
2891
[email protected]2df19bb2010-08-25 20:13:462892 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072893 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112894 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292895 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072896 session_deps_.net_log = log.bound().net_log();
2897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462898
[email protected]2df19bb2010-08-25 20:13:462899 // Since we have proxy, should use full url
2900 MockWrite data_writes1[] = {
2901 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2902 "Host: www.google.com\r\n"
2903 "Proxy-Connection: keep-alive\r\n\r\n"),
2904 };
2905
2906 MockRead data_reads1[] = {
2907 MockRead("HTTP/1.1 200 OK\r\n"),
2908 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2909 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062910 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462911 };
2912
2913 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2914 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072915 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062916 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462918
[email protected]49639fa2011-12-20 23:22:412919 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462920
[email protected]262eec82013-03-19 21:01:362921 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502923
[email protected]49639fa2011-12-20 23:22:412924 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462925 EXPECT_EQ(ERR_IO_PENDING, rv);
2926
2927 rv = callback1.WaitForResult();
2928 EXPECT_EQ(OK, rv);
2929
[email protected]58e32bb2013-01-21 18:23:252930 LoadTimingInfo load_timing_info;
2931 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2932 TestLoadTimingNotReused(load_timing_info,
2933 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2934
[email protected]2df19bb2010-08-25 20:13:462935 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502936 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462937
2938 EXPECT_TRUE(response->headers->IsKeepAlive());
2939 EXPECT_EQ(200, response->headers->response_code());
2940 EXPECT_EQ(100, response->headers->GetContentLength());
2941 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2942
2943 // The password prompt info should not be set.
2944 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2945}
2946
[email protected]7642b5ae2010-09-01 20:55:172947// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022948TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272949 HttpRequestInfo request;
2950 request.method = "GET";
2951 request.url = GURL("http://www.google.com/");
2952 request.load_flags = 0;
2953
[email protected]7642b5ae2010-09-01 20:55:172954 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072955 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112956 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292957 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072958 session_deps_.net_log = log.bound().net_log();
2959 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172960
[email protected]7642b5ae2010-09-01 20:55:172961 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462962 scoped_ptr<SpdyFrame> req(
2963 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172964 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2965
[email protected]23e482282013-06-14 16:08:022966 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2967 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172968 MockRead spdy_reads[] = {
2969 CreateMockRead(*resp),
2970 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062971 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172972 };
2973
[email protected]dd54bd82012-07-19 23:44:572974 DelayedSocketData spdy_data(
2975 1, // wait for one write to finish before reading.
2976 spdy_reads, arraysize(spdy_reads),
2977 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072978 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172979
[email protected]8ddf8322012-02-23 18:08:062980 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022981 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172983
[email protected]49639fa2011-12-20 23:22:412984 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172985
[email protected]262eec82013-03-19 21:01:362986 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502988
[email protected]49639fa2011-12-20 23:22:412989 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172990 EXPECT_EQ(ERR_IO_PENDING, rv);
2991
2992 rv = callback1.WaitForResult();
2993 EXPECT_EQ(OK, rv);
2994
[email protected]58e32bb2013-01-21 18:23:252995 LoadTimingInfo load_timing_info;
2996 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2997 TestLoadTimingNotReused(load_timing_info,
2998 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2999
[email protected]7642b5ae2010-09-01 20:55:173000 const HttpResponseInfo* response = trans->GetResponseInfo();
3001 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503002 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173003 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3004
3005 std::string response_data;
3006 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233007 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173008}
3009
[email protected]dc7bd1c52010-11-12 00:01:133010// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023011TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273012 HttpRequestInfo request;
3013 request.method = "GET";
3014 request.url = GURL("http://www.google.com/");
3015 request.load_flags = 0;
3016
[email protected]79cb5c12011-09-12 13:12:043017 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073018 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043019 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293020 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073021 session_deps_.net_log = log.bound().net_log();
3022 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133023
[email protected]dc7bd1c52010-11-12 00:01:133024 // The first request will be a bare GET, the second request will be a
3025 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193026 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463027 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133028 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463029 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133030 };
[email protected]ff98d7f02012-03-22 21:44:193031 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463032 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3033 arraysize(kExtraAuthorizationHeaders) / 2,
3034 false,
3035 3,
3036 LOWEST,
3037 false));
[email protected]dc7bd1c52010-11-12 00:01:133038 MockWrite spdy_writes[] = {
3039 CreateMockWrite(*req_get, 1),
3040 CreateMockWrite(*req_get_authorization, 4),
3041 };
3042
3043 // The first response is a 407 proxy authentication challenge, and the second
3044 // response will be a 200 response since the second request includes a valid
3045 // Authorization header.
3046 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463047 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133048 };
[email protected]ff98d7f02012-03-22 21:44:193049 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023050 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133051 "407 Proxy Authentication Required",
3052 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3053 1));
[email protected]ff98d7f02012-03-22 21:44:193054 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023055 spdy_util_.ConstructSpdyBodyFrame(1, true));
3056 scoped_ptr<SpdyFrame> resp_data(
3057 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3058 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133059 MockRead spdy_reads[] = {
3060 CreateMockRead(*resp_authentication, 2),
3061 CreateMockRead(*body_authentication, 3),
3062 CreateMockRead(*resp_data, 5),
3063 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063064 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133065 };
3066
[email protected]dd54bd82012-07-19 23:44:573067 OrderedSocketData data(
3068 spdy_reads, arraysize(spdy_reads),
3069 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073070 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133071
[email protected]8ddf8322012-02-23 18:08:063072 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023073 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133077
[email protected]262eec82013-03-19 21:01:363078 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133080
[email protected]49639fa2011-12-20 23:22:413081 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133082 EXPECT_EQ(ERR_IO_PENDING, rv);
3083
3084 rv = callback1.WaitForResult();
3085 EXPECT_EQ(OK, rv);
3086
3087 const HttpResponseInfo* const response = trans->GetResponseInfo();
3088
3089 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503090 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133091 EXPECT_EQ(407, response->headers->response_code());
3092 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043093 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133094
[email protected]49639fa2011-12-20 23:22:413095 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133096
[email protected]49639fa2011-12-20 23:22:413097 rv = trans->RestartWithAuth(
3098 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133099 EXPECT_EQ(ERR_IO_PENDING, rv);
3100
3101 rv = callback2.WaitForResult();
3102 EXPECT_EQ(OK, rv);
3103
3104 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3105
3106 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503107 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133108 EXPECT_EQ(200, response_restart->headers->response_code());
3109 // The password prompt info should not be set.
3110 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3111}
3112
[email protected]d9da5fe2010-10-13 22:37:163113// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023114TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273115 HttpRequestInfo request;
3116 request.method = "GET";
3117 request.url = GURL("https://www.google.com/");
3118 request.load_flags = 0;
3119
[email protected]d9da5fe2010-10-13 22:37:163120 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073121 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113122 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293123 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073124 session_deps_.net_log = log.bound().net_log();
3125 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163126
[email protected]262eec82013-03-19 21:01:363127 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163129
[email protected]d9da5fe2010-10-13 22:37:163130 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543131 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3132 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163133 // fetch https://www.google.com/ via HTTP
3134
3135 const char get[] = "GET / HTTP/1.1\r\n"
3136 "Host: www.google.com\r\n"
3137 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193138 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023139 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3140 scoped_ptr<SpdyFrame> conn_resp(
3141 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163142 const char resp[] = "HTTP/1.1 200 OK\r\n"
3143 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193144 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023145 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193146 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023147 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193148 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203149 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043150
3151 MockWrite spdy_writes[] = {
3152 CreateMockWrite(*connect, 1),
3153 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463154 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043155 };
3156
[email protected]d9da5fe2010-10-13 22:37:163157 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063158 CreateMockRead(*conn_resp, 2, ASYNC),
3159 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3160 CreateMockRead(*wrapped_body, 6, ASYNC),
3161 CreateMockRead(*wrapped_body, 7, ASYNC),
3162 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163163 };
3164
[email protected]dd54bd82012-07-19 23:44:573165 OrderedSocketData spdy_data(
3166 spdy_reads, arraysize(spdy_reads),
3167 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073168 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163169
[email protected]8ddf8322012-02-23 18:08:063170 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023171 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063173 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163174 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463175 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073176 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163177
[email protected]49639fa2011-12-20 23:22:413178 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163179
[email protected]49639fa2011-12-20 23:22:413180 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163181 EXPECT_EQ(ERR_IO_PENDING, rv);
3182
3183 rv = callback1.WaitForResult();
3184 EXPECT_EQ(OK, rv);
3185
[email protected]58e32bb2013-01-21 18:23:253186 LoadTimingInfo load_timing_info;
3187 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3188 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3189
[email protected]d9da5fe2010-10-13 22:37:163190 const HttpResponseInfo* response = trans->GetResponseInfo();
3191 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503192 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163193 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3194
3195 std::string response_data;
3196 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3197 EXPECT_EQ("1234567890", response_data);
3198}
3199
3200// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023201TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273202 HttpRequestInfo request;
3203 request.method = "GET";
3204 request.url = GURL("https://www.google.com/");
3205 request.load_flags = 0;
3206
[email protected]d9da5fe2010-10-13 22:37:163207 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073208 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113209 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293210 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073211 session_deps_.net_log = log.bound().net_log();
3212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163213
[email protected]262eec82013-03-19 21:01:363214 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163216
[email protected]d9da5fe2010-10-13 22:37:163217 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543218 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3219 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163220 // fetch https://www.google.com/ via SPDY
3221 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463222 scoped_ptr<SpdyFrame> get(
3223 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023224 scoped_ptr<SpdyFrame> wrapped_get(
3225 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3226 scoped_ptr<SpdyFrame> conn_resp(
3227 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3228 scoped_ptr<SpdyFrame> get_resp(
3229 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193230 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023231 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3232 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3233 scoped_ptr<SpdyFrame> wrapped_body(
3234 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193235 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203236 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193237 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203238 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043239
3240 MockWrite spdy_writes[] = {
3241 CreateMockWrite(*connect, 1),
3242 CreateMockWrite(*wrapped_get, 3),
3243 CreateMockWrite(*window_update_get_resp, 5),
3244 CreateMockWrite(*window_update_body, 7),
3245 };
3246
[email protected]d9da5fe2010-10-13 22:37:163247 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063248 CreateMockRead(*conn_resp, 2, ASYNC),
3249 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3250 CreateMockRead(*wrapped_body, 6, ASYNC),
3251 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163252 };
3253
[email protected]dd54bd82012-07-19 23:44:573254 OrderedSocketData spdy_data(
3255 spdy_reads, arraysize(spdy_reads),
3256 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073257 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163258
[email protected]8ddf8322012-02-23 18:08:063259 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023260 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063262 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023263 ssl2.SetNextProto(GetParam());
3264 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073265 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163266
[email protected]49639fa2011-12-20 23:22:413267 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163268
[email protected]49639fa2011-12-20 23:22:413269 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163270 EXPECT_EQ(ERR_IO_PENDING, rv);
3271
3272 rv = callback1.WaitForResult();
3273 EXPECT_EQ(OK, rv);
3274
[email protected]58e32bb2013-01-21 18:23:253275 LoadTimingInfo load_timing_info;
3276 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3277 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3278
[email protected]d9da5fe2010-10-13 22:37:163279 const HttpResponseInfo* response = trans->GetResponseInfo();
3280 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503281 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163282 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3283
3284 std::string response_data;
3285 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233286 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163287}
3288
3289// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023290TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273291 HttpRequestInfo request;
3292 request.method = "GET";
3293 request.url = GURL("https://www.google.com/");
3294 request.load_flags = 0;
3295
[email protected]d9da5fe2010-10-13 22:37:163296 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073297 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113298 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293299 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.net_log = log.bound().net_log();
3301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163302
[email protected]262eec82013-03-19 21:01:363303 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163305
[email protected]d9da5fe2010-10-13 22:37:163306 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543307 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3308 LOWEST));
[email protected]c10b20852013-05-15 21:29:203309 scoped_ptr<SpdyFrame> get(
3310 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163311
3312 MockWrite spdy_writes[] = {
3313 CreateMockWrite(*connect, 1),
3314 CreateMockWrite(*get, 3),
3315 };
3316
[email protected]23e482282013-06-14 16:08:023317 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3318 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163319 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063320 CreateMockRead(*resp, 2, ASYNC),
3321 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163322 };
3323
[email protected]dd54bd82012-07-19 23:44:573324 OrderedSocketData spdy_data(
3325 spdy_reads, arraysize(spdy_reads),
3326 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073327 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163328
[email protected]8ddf8322012-02-23 18:08:063329 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023330 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063332 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023333 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163335
[email protected]49639fa2011-12-20 23:22:413336 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163337
[email protected]49639fa2011-12-20 23:22:413338 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163339 EXPECT_EQ(ERR_IO_PENDING, rv);
3340
3341 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173342 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163343
[email protected]4eddbc732012-08-09 05:40:173344 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163345}
3346
[email protected]f6c63db52013-02-02 00:35:223347// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3348// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023349TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223350 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3351 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073352 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223353 "https://proxy:70"));
3354 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073355 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223356 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073357 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223358
3359 HttpRequestInfo request1;
3360 request1.method = "GET";
3361 request1.url = GURL("https://www.google.com/");
3362 request1.load_flags = 0;
3363
3364 HttpRequestInfo request2;
3365 request2.method = "GET";
3366 request2.url = GURL("https://news.google.com/");
3367 request2.load_flags = 0;
3368
3369 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543370 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3371 LOWEST));
[email protected]23e482282013-06-14 16:08:023372 scoped_ptr<SpdyFrame> conn_resp1(
3373 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223374
3375 // Fetch https://www.google.com/ via HTTP.
3376 const char get1[] = "GET / HTTP/1.1\r\n"
3377 "Host: www.google.com\r\n"
3378 "Connection: keep-alive\r\n\r\n";
3379 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023380 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223381 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3382 "Content-Length: 1\r\n\r\n";
3383 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023384 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3385 scoped_ptr<SpdyFrame> wrapped_body1(
3386 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223387 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203388 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223389
3390 // CONNECT to news.google.com:443 via SPDY.
[email protected]601e03f12014-04-06 16:26:393391 SpdySynStreamIR connect2_ir(3);
3392 spdy_util_.SetPriority(LOWEST, &connect2_ir);
3393 connect2_ir.SetHeader(spdy_util_.GetMethodKey(), "CONNECT");
3394 connect2_ir.SetHeader(spdy_util_.GetPathKey(), "news.google.com:443");
3395 connect2_ir.SetHeader(spdy_util_.GetHostKey(), "news.google.com");
3396 spdy_util_.MaybeAddVersionHeader(&connect2_ir);
[email protected]f6c63db52013-02-02 00:35:223397 scoped_ptr<SpdyFrame> connect2(
[email protected]601e03f12014-04-06 16:26:393398 spdy_util_.CreateFramer(false)->SerializeFrame(connect2_ir));
3399
[email protected]23e482282013-06-14 16:08:023400 scoped_ptr<SpdyFrame> conn_resp2(
3401 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223402
3403 // Fetch https://news.google.com/ via HTTP.
3404 const char get2[] = "GET / HTTP/1.1\r\n"
3405 "Host: news.google.com\r\n"
3406 "Connection: keep-alive\r\n\r\n";
3407 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023408 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223409 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3410 "Content-Length: 2\r\n\r\n";
3411 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023412 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223413 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023414 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223415
3416 MockWrite spdy_writes[] = {
3417 CreateMockWrite(*connect1, 0),
3418 CreateMockWrite(*wrapped_get1, 2),
3419 CreateMockWrite(*connect2, 5),
3420 CreateMockWrite(*wrapped_get2, 7),
3421 };
3422
3423 MockRead spdy_reads[] = {
3424 CreateMockRead(*conn_resp1, 1, ASYNC),
3425 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3426 CreateMockRead(*wrapped_body1, 4, ASYNC),
3427 CreateMockRead(*conn_resp2, 6, ASYNC),
3428 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3429 CreateMockRead(*wrapped_body2, 9, ASYNC),
3430 MockRead(ASYNC, 0, 10),
3431 };
3432
3433 DeterministicSocketData spdy_data(
3434 spdy_reads, arraysize(spdy_reads),
3435 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073436 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223437
3438 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023439 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073440 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223441 SSLSocketDataProvider ssl2(ASYNC, OK);
3442 ssl2.was_npn_negotiated = false;
3443 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073444 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223445 SSLSocketDataProvider ssl3(ASYNC, OK);
3446 ssl3.was_npn_negotiated = false;
3447 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073448 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223449
3450 TestCompletionCallback callback;
3451
[email protected]262eec82013-03-19 21:01:363452 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503453 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223454 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3455 EXPECT_EQ(ERR_IO_PENDING, rv);
3456 // The first connect and request, each of their responses, and the body.
3457 spdy_data.RunFor(5);
3458
3459 rv = callback.WaitForResult();
3460 EXPECT_EQ(OK, rv);
3461
3462 LoadTimingInfo load_timing_info;
3463 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3464 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3465
3466 const HttpResponseInfo* response = trans->GetResponseInfo();
3467 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503468 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223469 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3470
3471 std::string response_data;
3472 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503473 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223474
[email protected]262eec82013-03-19 21:01:363475 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503476 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223477 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3478 EXPECT_EQ(ERR_IO_PENDING, rv);
3479
3480 // The second connect and request, each of their responses, and the body.
3481 spdy_data.RunFor(5);
3482 rv = callback.WaitForResult();
3483 EXPECT_EQ(OK, rv);
3484
3485 LoadTimingInfo load_timing_info2;
3486 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3487 // Even though the SPDY connection is reused, a new tunnelled connection has
3488 // to be created, so the socket's load timing looks like a fresh connection.
3489 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3490
3491 // The requests should have different IDs, since they each are using their own
3492 // separate stream.
3493 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3494
[email protected]90499482013-06-01 00:39:503495 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223496}
3497
3498// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3499// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023500TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223501 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3502 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073503 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223504 "https://proxy:70"));
3505 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073506 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223507 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073508 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223509
3510 HttpRequestInfo request1;
3511 request1.method = "GET";
3512 request1.url = GURL("https://www.google.com/");
3513 request1.load_flags = 0;
3514
3515 HttpRequestInfo request2;
3516 request2.method = "GET";
3517 request2.url = GURL("https://www.google.com/2");
3518 request2.load_flags = 0;
3519
3520 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543521 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3522 LOWEST));
[email protected]23e482282013-06-14 16:08:023523 scoped_ptr<SpdyFrame> conn_resp1(
3524 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223525
3526 // Fetch https://www.google.com/ via HTTP.
3527 const char get1[] = "GET / HTTP/1.1\r\n"
3528 "Host: www.google.com\r\n"
3529 "Connection: keep-alive\r\n\r\n";
3530 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023531 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223532 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3533 "Content-Length: 1\r\n\r\n";
3534 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023535 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3536 scoped_ptr<SpdyFrame> wrapped_body1(
3537 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223538 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203539 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223540
3541 // Fetch https://www.google.com/2 via HTTP.
3542 const char get2[] = "GET /2 HTTP/1.1\r\n"
3543 "Host: www.google.com\r\n"
3544 "Connection: keep-alive\r\n\r\n";
3545 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023546 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223547 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3548 "Content-Length: 2\r\n\r\n";
3549 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023550 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223551 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023552 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223553
3554 MockWrite spdy_writes[] = {
3555 CreateMockWrite(*connect1, 0),
3556 CreateMockWrite(*wrapped_get1, 2),
3557 CreateMockWrite(*wrapped_get2, 5),
3558 };
3559
3560 MockRead spdy_reads[] = {
3561 CreateMockRead(*conn_resp1, 1, ASYNC),
3562 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3563 CreateMockRead(*wrapped_body1, 4, ASYNC),
3564 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3565 CreateMockRead(*wrapped_body2, 7, ASYNC),
3566 MockRead(ASYNC, 0, 8),
3567 };
3568
3569 DeterministicSocketData spdy_data(
3570 spdy_reads, arraysize(spdy_reads),
3571 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073572 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223573
3574 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023575 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073576 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223577 SSLSocketDataProvider ssl2(ASYNC, OK);
3578 ssl2.was_npn_negotiated = false;
3579 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073580 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223581
3582 TestCompletionCallback callback;
3583
[email protected]262eec82013-03-19 21:01:363584 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503585 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223586 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3587 EXPECT_EQ(ERR_IO_PENDING, rv);
3588 // The first connect and request, each of their responses, and the body.
3589 spdy_data.RunFor(5);
3590
3591 rv = callback.WaitForResult();
3592 EXPECT_EQ(OK, rv);
3593
3594 LoadTimingInfo load_timing_info;
3595 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3596 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3597
3598 const HttpResponseInfo* response = trans->GetResponseInfo();
3599 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503600 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3602
3603 std::string response_data;
3604 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503605 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223606 trans.reset();
3607
[email protected]262eec82013-03-19 21:01:363608 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223610 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3611 EXPECT_EQ(ERR_IO_PENDING, rv);
3612
3613 // The second request, response, and body. There should not be a second
3614 // connect.
3615 spdy_data.RunFor(3);
3616 rv = callback.WaitForResult();
3617 EXPECT_EQ(OK, rv);
3618
3619 LoadTimingInfo load_timing_info2;
3620 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3621 TestLoadTimingReused(load_timing_info2);
3622
3623 // The requests should have the same ID.
3624 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3625
[email protected]90499482013-06-01 00:39:503626 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223627}
3628
3629// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3630// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023631TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223632 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3633 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073634 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223635 "https://proxy:70"));
3636 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073637 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223638 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073639 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223640
3641 HttpRequestInfo request1;
3642 request1.method = "GET";
3643 request1.url = GURL("http://www.google.com/");
3644 request1.load_flags = 0;
3645
3646 HttpRequestInfo request2;
3647 request2.method = "GET";
3648 request2.url = GURL("http://news.google.com/");
3649 request2.load_flags = 0;
3650
3651 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023652 scoped_ptr<SpdyHeaderBlock> headers(
3653 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233654 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023655 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3656 scoped_ptr<SpdyFrame> get_resp1(
3657 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3658 scoped_ptr<SpdyFrame> body1(
3659 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223660
3661 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023662 scoped_ptr<SpdyHeaderBlock> headers2(
3663 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233664 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023665 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3666 scoped_ptr<SpdyFrame> get_resp2(
3667 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3668 scoped_ptr<SpdyFrame> body2(
3669 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223670
3671 MockWrite spdy_writes[] = {
3672 CreateMockWrite(*get1, 0),
3673 CreateMockWrite(*get2, 3),
3674 };
3675
3676 MockRead spdy_reads[] = {
3677 CreateMockRead(*get_resp1, 1, ASYNC),
3678 CreateMockRead(*body1, 2, ASYNC),
3679 CreateMockRead(*get_resp2, 4, ASYNC),
3680 CreateMockRead(*body2, 5, ASYNC),
3681 MockRead(ASYNC, 0, 6),
3682 };
3683
3684 DeterministicSocketData spdy_data(
3685 spdy_reads, arraysize(spdy_reads),
3686 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073687 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223688
3689 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023690 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073691 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223692
3693 TestCompletionCallback callback;
3694
[email protected]262eec82013-03-19 21:01:363695 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503696 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223697 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3698 EXPECT_EQ(ERR_IO_PENDING, rv);
3699 spdy_data.RunFor(2);
3700
3701 rv = callback.WaitForResult();
3702 EXPECT_EQ(OK, rv);
3703
3704 LoadTimingInfo load_timing_info;
3705 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3706 TestLoadTimingNotReused(load_timing_info,
3707 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3708
3709 const HttpResponseInfo* response = trans->GetResponseInfo();
3710 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503711 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223712 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3713
3714 std::string response_data;
3715 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503716 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223717 spdy_data.RunFor(1);
3718 EXPECT_EQ(1, callback.WaitForResult());
3719 // Delete the first request, so the second one can reuse the socket.
3720 trans.reset();
3721
[email protected]262eec82013-03-19 21:01:363722 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223724 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3725 EXPECT_EQ(ERR_IO_PENDING, rv);
3726
3727 spdy_data.RunFor(2);
3728 rv = callback.WaitForResult();
3729 EXPECT_EQ(OK, rv);
3730
3731 LoadTimingInfo load_timing_info2;
3732 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3733 TestLoadTimingReused(load_timing_info2);
3734
3735 // The requests should have the same ID.
3736 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3737
[email protected]90499482013-06-01 00:39:503738 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223739 spdy_data.RunFor(1);
3740 EXPECT_EQ(2, callback.WaitForResult());
3741}
3742
[email protected]2df19bb2010-08-25 20:13:463743// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023744TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463745 HttpRequestInfo request;
3746 request.method = "GET";
3747 request.url = GURL("http://www.google.com/");
3748 // when the no authentication data flag is set.
3749 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3750
[email protected]79cb5c12011-09-12 13:12:043751 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073752 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043753 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293754 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073755 session_deps_.net_log = log.bound().net_log();
3756 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273757
[email protected]2df19bb2010-08-25 20:13:463758 // Since we have proxy, should use full url
3759 MockWrite data_writes1[] = {
3760 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3761 "Host: www.google.com\r\n"
3762 "Proxy-Connection: keep-alive\r\n\r\n"),
3763
3764 // After calling trans->RestartWithAuth(), this is the request we should
3765 // be issuing -- the final header line contains the credentials.
3766 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3767 "Host: www.google.com\r\n"
3768 "Proxy-Connection: keep-alive\r\n"
3769 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3770 };
3771
3772 // The proxy responds to the GET with a 407, using a persistent
3773 // connection.
3774 MockRead data_reads1[] = {
3775 // No credentials.
3776 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3777 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3778 MockRead("Proxy-Connection: keep-alive\r\n"),
3779 MockRead("Content-Length: 0\r\n\r\n"),
3780
3781 MockRead("HTTP/1.1 200 OK\r\n"),
3782 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3783 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063784 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463785 };
3786
3787 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3788 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073789 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063790 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073791 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463792
[email protected]49639fa2011-12-20 23:22:413793 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463794
[email protected]262eec82013-03-19 21:01:363795 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503796 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503797
[email protected]49639fa2011-12-20 23:22:413798 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463799 EXPECT_EQ(ERR_IO_PENDING, rv);
3800
3801 rv = callback1.WaitForResult();
3802 EXPECT_EQ(OK, rv);
3803
[email protected]58e32bb2013-01-21 18:23:253804 LoadTimingInfo load_timing_info;
3805 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3806 TestLoadTimingNotReused(load_timing_info,
3807 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3808
[email protected]2df19bb2010-08-25 20:13:463809 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503810 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503811 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463812 EXPECT_EQ(407, response->headers->response_code());
3813 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043814 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463815
[email protected]49639fa2011-12-20 23:22:413816 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463817
[email protected]49639fa2011-12-20 23:22:413818 rv = trans->RestartWithAuth(
3819 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463820 EXPECT_EQ(ERR_IO_PENDING, rv);
3821
3822 rv = callback2.WaitForResult();
3823 EXPECT_EQ(OK, rv);
3824
[email protected]58e32bb2013-01-21 18:23:253825 load_timing_info = LoadTimingInfo();
3826 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3827 // Retrying with HTTP AUTH is considered to be reusing a socket.
3828 TestLoadTimingReused(load_timing_info);
3829
[email protected]2df19bb2010-08-25 20:13:463830 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503831 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463832
3833 EXPECT_TRUE(response->headers->IsKeepAlive());
3834 EXPECT_EQ(200, response->headers->response_code());
3835 EXPECT_EQ(100, response->headers->GetContentLength());
3836 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3837
3838 // The password prompt info should not be set.
3839 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3840}
3841
[email protected]23e482282013-06-14 16:08:023842void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083843 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423844 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083845 request.method = "GET";
3846 request.url = GURL("https://www.google.com/");
3847 request.load_flags = 0;
3848
[email protected]cb9bf6ca2011-01-28 13:15:273849 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073850 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073851 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273852
[email protected]c744cf22009-02-27 07:28:083853 // Since we have proxy, should try to establish tunnel.
3854 MockWrite data_writes[] = {
3855 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453856 "Host: www.google.com\r\n"
3857 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083858 };
3859
3860 MockRead data_reads[] = {
3861 status,
3862 MockRead("Content-Length: 10\r\n\r\n"),
3863 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063864 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083865 };
3866
[email protected]31a2bfe2010-02-09 08:03:393867 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3868 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073869 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083870
[email protected]49639fa2011-12-20 23:22:413871 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083872
[email protected]262eec82013-03-19 21:01:363873 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503874 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503875
[email protected]49639fa2011-12-20 23:22:413876 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423877 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083878
3879 rv = callback.WaitForResult();
3880 EXPECT_EQ(expected_status, rv);
3881}
3882
[email protected]23e482282013-06-14 16:08:023883void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233884 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083885 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423886 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083887}
3888
[email protected]23e482282013-06-14 16:08:023889TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083890 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3891}
3892
[email protected]23e482282013-06-14 16:08:023893TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083894 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3895}
3896
[email protected]23e482282013-06-14 16:08:023897TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083898 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3899}
3900
[email protected]23e482282013-06-14 16:08:023901TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083902 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3903}
3904
[email protected]23e482282013-06-14 16:08:023905TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083906 ConnectStatusHelper(
3907 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3908}
3909
[email protected]23e482282013-06-14 16:08:023910TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083911 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3912}
3913
[email protected]23e482282013-06-14 16:08:023914TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083915 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3916}
3917
[email protected]23e482282013-06-14 16:08:023918TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083919 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3920}
3921
[email protected]23e482282013-06-14 16:08:023922TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083923 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3924}
3925
[email protected]23e482282013-06-14 16:08:023926TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083927 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3928}
3929
[email protected]23e482282013-06-14 16:08:023930TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083931 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3932}
3933
[email protected]23e482282013-06-14 16:08:023934TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083935 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3936}
3937
[email protected]23e482282013-06-14 16:08:023938TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083939 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3940}
3941
[email protected]23e482282013-06-14 16:08:023942TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083943 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3944}
3945
[email protected]23e482282013-06-14 16:08:023946TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083947 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3948}
3949
[email protected]23e482282013-06-14 16:08:023950TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083951 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3952}
3953
[email protected]23e482282013-06-14 16:08:023954TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083955 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3956}
3957
[email protected]23e482282013-06-14 16:08:023958TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083959 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3960}
3961
[email protected]23e482282013-06-14 16:08:023962TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083963 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3964}
3965
[email protected]23e482282013-06-14 16:08:023966TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083967 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3968}
3969
[email protected]23e482282013-06-14 16:08:023970TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083971 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3972}
3973
[email protected]23e482282013-06-14 16:08:023974TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083975 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3976}
3977
[email protected]23e482282013-06-14 16:08:023978TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083979 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3980}
3981
[email protected]23e482282013-06-14 16:08:023982TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083983 ConnectStatusHelperWithExpectedStatus(
3984 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543985 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083986}
3987
[email protected]23e482282013-06-14 16:08:023988TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083989 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3990}
3991
[email protected]23e482282013-06-14 16:08:023992TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083993 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3994}
3995
[email protected]23e482282013-06-14 16:08:023996TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083997 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3998}
3999
[email protected]23e482282013-06-14 16:08:024000TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084001 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4002}
4003
[email protected]23e482282013-06-14 16:08:024004TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084005 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4006}
4007
[email protected]23e482282013-06-14 16:08:024008TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084009 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4010}
4011
[email protected]23e482282013-06-14 16:08:024012TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084013 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4014}
4015
[email protected]23e482282013-06-14 16:08:024016TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084017 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4018}
4019
[email protected]23e482282013-06-14 16:08:024020TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084021 ConnectStatusHelper(
4022 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4023}
4024
[email protected]23e482282013-06-14 16:08:024025TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084026 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4027}
4028
[email protected]23e482282013-06-14 16:08:024029TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084030 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4031}
4032
[email protected]23e482282013-06-14 16:08:024033TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084034 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4035}
4036
[email protected]23e482282013-06-14 16:08:024037TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084038 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4039}
4040
[email protected]23e482282013-06-14 16:08:024041TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084042 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4043}
4044
[email protected]23e482282013-06-14 16:08:024045TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084046 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4047}
4048
[email protected]23e482282013-06-14 16:08:024049TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084050 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4051}
4052
[email protected]038e9a32008-10-08 22:40:164053// Test the flow when both the proxy server AND origin server require
4054// authentication. Again, this uses basic auth for both since that is
4055// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024056TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274057 HttpRequestInfo request;
4058 request.method = "GET";
4059 request.url = GURL("http://www.google.com/");
4060 request.load_flags = 0;
4061
[email protected]038e9a32008-10-08 22:40:164062 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074063 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4065
4066 scoped_ptr<HttpTransaction> trans(
4067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:164068
[email protected]f9ee6b52008-11-08 06:46:234069 MockWrite data_writes1[] = {
4070 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4071 "Host: www.google.com\r\n"
4072 "Proxy-Connection: keep-alive\r\n\r\n"),
4073 };
4074
[email protected]038e9a32008-10-08 22:40:164075 MockRead data_reads1[] = {
4076 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4077 // Give a couple authenticate options (only the middle one is actually
4078 // supported).
[email protected]22927ad2009-09-21 19:56:194079 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164080 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4081 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4082 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4083 // Large content-length -- won't matter, as connection will be reset.
4084 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064085 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164086 };
4087
4088 // After calling trans->RestartWithAuth() the first time, this is the
4089 // request we should be issuing -- the final header line contains the
4090 // proxy's credentials.
4091 MockWrite data_writes2[] = {
4092 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4093 "Host: www.google.com\r\n"
4094 "Proxy-Connection: keep-alive\r\n"
4095 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4096 };
4097
4098 // Now the proxy server lets the request pass through to origin server.
4099 // The origin server responds with a 401.
4100 MockRead data_reads2[] = {
4101 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4102 // Note: We are using the same realm-name as the proxy server. This is
4103 // completely valid, as realms are unique across hosts.
4104 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4105 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4106 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064107 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164108 };
4109
4110 // After calling trans->RestartWithAuth() the second time, we should send
4111 // the credentials for both the proxy and origin server.
4112 MockWrite data_writes3[] = {
4113 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4114 "Host: www.google.com\r\n"
4115 "Proxy-Connection: keep-alive\r\n"
4116 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4117 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4118 };
4119
4120 // Lastly we get the desired content.
4121 MockRead data_reads3[] = {
4122 MockRead("HTTP/1.0 200 OK\r\n"),
4123 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4124 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064125 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164126 };
4127
[email protected]31a2bfe2010-02-09 08:03:394128 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4129 data_writes1, arraysize(data_writes1));
4130 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4131 data_writes2, arraysize(data_writes2));
4132 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4133 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074134 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4135 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4136 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164137
[email protected]49639fa2011-12-20 23:22:414138 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164139
[email protected]49639fa2011-12-20 23:22:414140 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424141 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164142
4143 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424144 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164145
[email protected]1c773ea12009-04-28 19:58:424146 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504147 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044148 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164149
[email protected]49639fa2011-12-20 23:22:414150 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164151
[email protected]49639fa2011-12-20 23:22:414152 rv = trans->RestartWithAuth(
4153 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424154 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164155
4156 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424157 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164158
4159 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504160 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044161 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164162
[email protected]49639fa2011-12-20 23:22:414163 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164164
[email protected]49639fa2011-12-20 23:22:414165 rv = trans->RestartWithAuth(
4166 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424167 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164168
4169 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424170 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164171
4172 response = trans->GetResponseInfo();
4173 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4174 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164175}
[email protected]4ddaf2502008-10-23 18:26:194176
[email protected]ea9dc9a2009-09-05 00:43:324177// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4178// can't hook into its internals to cause it to generate predictable NTLM
4179// authorization headers.
4180#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294181// The NTLM authentication unit tests were generated by capturing the HTTP
4182// requests and responses using Fiddler 2 and inspecting the generated random
4183// bytes in the debugger.
4184
4185// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024186TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424187 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244188 request.method = "GET";
4189 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544190
4191 // Ensure load is not disrupted by flags which suppress behaviour specific
4192 // to other auth schemes.
4193 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244194
[email protected]cb9bf6ca2011-01-28 13:15:274195 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4196 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274198
[email protected]3f918782009-02-28 01:29:244199 MockWrite data_writes1[] = {
4200 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4201 "Host: 172.22.68.17\r\n"
4202 "Connection: keep-alive\r\n\r\n"),
4203 };
4204
4205 MockRead data_reads1[] = {
4206 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044207 // Negotiate and NTLM are often requested together. However, we only want
4208 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4209 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244210 MockRead("WWW-Authenticate: NTLM\r\n"),
4211 MockRead("Connection: close\r\n"),
4212 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364213 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244214 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064215 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244216 };
4217
4218 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224219 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244220 // request we should be issuing -- the final header line contains a Type
4221 // 1 message.
4222 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4223 "Host: 172.22.68.17\r\n"
4224 "Connection: keep-alive\r\n"
4225 "Authorization: NTLM "
4226 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4227
4228 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4229 // (the credentials for the origin server). The second request continues
4230 // on the same connection.
4231 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4232 "Host: 172.22.68.17\r\n"
4233 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294234 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4235 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4236 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4237 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4238 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244239 };
4240
4241 MockRead data_reads2[] = {
4242 // The origin server responds with a Type 2 message.
4243 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4244 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294245 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244246 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4247 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4248 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4249 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4250 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4251 "BtAAAAAAA=\r\n"),
4252 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364253 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244254 MockRead("You are not authorized to view this page\r\n"),
4255
4256 // Lastly we get the desired content.
4257 MockRead("HTTP/1.1 200 OK\r\n"),
4258 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4259 MockRead("Content-Length: 13\r\n\r\n"),
4260 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064261 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244262 };
4263
[email protected]31a2bfe2010-02-09 08:03:394264 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4265 data_writes1, arraysize(data_writes1));
4266 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4267 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074268 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4269 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244270
[email protected]49639fa2011-12-20 23:22:414271 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244272
[email protected]262eec82013-03-19 21:01:364273 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504274 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504275
[email protected]49639fa2011-12-20 23:22:414276 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424277 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244278
4279 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424280 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244281
[email protected]0757e7702009-03-27 04:00:224282 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4283
[email protected]1c773ea12009-04-28 19:58:424284 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044285 ASSERT_FALSE(response == NULL);
4286 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244287
[email protected]49639fa2011-12-20 23:22:414288 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254289
[email protected]f3cf9802011-10-28 18:44:584290 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414291 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254292 EXPECT_EQ(ERR_IO_PENDING, rv);
4293
4294 rv = callback2.WaitForResult();
4295 EXPECT_EQ(OK, rv);
4296
4297 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4298
4299 response = trans->GetResponseInfo();
4300 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254301 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4302
[email protected]49639fa2011-12-20 23:22:414303 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244304
[email protected]49639fa2011-12-20 23:22:414305 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424306 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244307
[email protected]0757e7702009-03-27 04:00:224308 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424309 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244310
4311 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504312 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244313 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4314 EXPECT_EQ(13, response->headers->GetContentLength());
4315}
4316
[email protected]385a4672009-03-11 22:21:294317// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024318TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424319 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294320 request.method = "GET";
4321 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4322 request.load_flags = 0;
4323
[email protected]cb9bf6ca2011-01-28 13:15:274324 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4325 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074326 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274327
[email protected]385a4672009-03-11 22:21:294328 MockWrite data_writes1[] = {
4329 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4330 "Host: 172.22.68.17\r\n"
4331 "Connection: keep-alive\r\n\r\n"),
4332 };
4333
4334 MockRead data_reads1[] = {
4335 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044336 // Negotiate and NTLM are often requested together. However, we only want
4337 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4338 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294339 MockRead("WWW-Authenticate: NTLM\r\n"),
4340 MockRead("Connection: close\r\n"),
4341 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364342 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294343 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064344 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294345 };
4346
4347 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224348 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294349 // request we should be issuing -- the final header line contains a Type
4350 // 1 message.
4351 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4352 "Host: 172.22.68.17\r\n"
4353 "Connection: keep-alive\r\n"
4354 "Authorization: NTLM "
4355 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4356
4357 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4358 // (the credentials for the origin server). The second request continues
4359 // on the same connection.
4360 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4361 "Host: 172.22.68.17\r\n"
4362 "Connection: keep-alive\r\n"
4363 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4364 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4365 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4366 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4367 "4Ww7b7E=\r\n\r\n"),
4368 };
4369
4370 MockRead data_reads2[] = {
4371 // The origin server responds with a Type 2 message.
4372 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4373 MockRead("WWW-Authenticate: NTLM "
4374 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4375 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4376 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4377 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4378 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4379 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4380 "BtAAAAAAA=\r\n"),
4381 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364382 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294383 MockRead("You are not authorized to view this page\r\n"),
4384
4385 // Wrong password.
4386 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294387 MockRead("WWW-Authenticate: NTLM\r\n"),
4388 MockRead("Connection: close\r\n"),
4389 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364390 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294391 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064392 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294393 };
4394
4395 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224396 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294397 // request we should be issuing -- the final header line contains a Type
4398 // 1 message.
4399 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4400 "Host: 172.22.68.17\r\n"
4401 "Connection: keep-alive\r\n"
4402 "Authorization: NTLM "
4403 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4404
4405 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4406 // (the credentials for the origin server). The second request continues
4407 // on the same connection.
4408 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4409 "Host: 172.22.68.17\r\n"
4410 "Connection: keep-alive\r\n"
4411 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4412 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4413 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4414 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4415 "+4MUm7c=\r\n\r\n"),
4416 };
4417
4418 MockRead data_reads3[] = {
4419 // The origin server responds with a Type 2 message.
4420 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4421 MockRead("WWW-Authenticate: NTLM "
4422 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4423 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4424 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4425 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4426 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4427 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4428 "BtAAAAAAA=\r\n"),
4429 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364430 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294431 MockRead("You are not authorized to view this page\r\n"),
4432
4433 // Lastly we get the desired content.
4434 MockRead("HTTP/1.1 200 OK\r\n"),
4435 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4436 MockRead("Content-Length: 13\r\n\r\n"),
4437 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064438 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294439 };
4440
[email protected]31a2bfe2010-02-09 08:03:394441 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4442 data_writes1, arraysize(data_writes1));
4443 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4444 data_writes2, arraysize(data_writes2));
4445 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4446 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074447 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4448 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4449 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294450
[email protected]49639fa2011-12-20 23:22:414451 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294452
[email protected]262eec82013-03-19 21:01:364453 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504455
[email protected]49639fa2011-12-20 23:22:414456 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424457 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294458
4459 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424460 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294461
[email protected]0757e7702009-03-27 04:00:224462 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294463
[email protected]1c773ea12009-04-28 19:58:424464 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504465 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044466 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294467
[email protected]49639fa2011-12-20 23:22:414468 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294469
[email protected]0757e7702009-03-27 04:00:224470 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584471 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414472 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424473 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294474
[email protected]10af5fe72011-01-31 16:17:254475 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424476 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294477
[email protected]0757e7702009-03-27 04:00:224478 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414479 TestCompletionCallback callback3;
4480 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424481 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254482 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424483 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224484 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4485
4486 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044487 ASSERT_FALSE(response == NULL);
4488 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224489
[email protected]49639fa2011-12-20 23:22:414490 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224491
4492 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584493 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414494 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254495 EXPECT_EQ(ERR_IO_PENDING, rv);
4496
4497 rv = callback4.WaitForResult();
4498 EXPECT_EQ(OK, rv);
4499
4500 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4501
[email protected]49639fa2011-12-20 23:22:414502 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254503
4504 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414505 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424506 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224507
4508 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424509 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224510
[email protected]385a4672009-03-11 22:21:294511 response = trans->GetResponseInfo();
4512 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4513 EXPECT_EQ(13, response->headers->GetContentLength());
4514}
[email protected]ea9dc9a2009-09-05 00:43:324515#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294516
[email protected]4ddaf2502008-10-23 18:26:194517// Test reading a server response which has only headers, and no body.
4518// After some maximum number of bytes is consumed, the transaction should
4519// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024520TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424521 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194522 request.method = "GET";
4523 request.url = GURL("http://www.google.com/");
4524 request.load_flags = 0;
4525
[email protected]3fe8d2f82013-10-17 08:56:074526 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274527 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074528 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274529
[email protected]b75b7b2f2009-10-06 00:54:534530 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434531 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534532 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194533
4534 MockRead data_reads[] = {
4535 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064536 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194537 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064538 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194539 };
[email protected]31a2bfe2010-02-09 08:03:394540 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074541 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194542
[email protected]49639fa2011-12-20 23:22:414543 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194544
[email protected]49639fa2011-12-20 23:22:414545 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424546 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194547
4548 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424549 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194550
[email protected]1c773ea12009-04-28 19:58:424551 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194552 EXPECT_TRUE(response == NULL);
4553}
[email protected]f4e426b2008-11-05 00:24:494554
4555// Make sure that we don't try to reuse a TCPClientSocket when failing to
4556// establish tunnel.
4557// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024558TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234559 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274560 HttpRequestInfo request;
4561 request.method = "GET";
4562 request.url = GURL("https://www.google.com/");
4563 request.load_flags = 0;
4564
[email protected]f4e426b2008-11-05 00:24:494565 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074566 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014567
[email protected]bb88e1d32013-05-03 23:11:074568 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494569
[email protected]262eec82013-03-19 21:01:364570 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504571 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494572
[email protected]f4e426b2008-11-05 00:24:494573 // Since we have proxy, should try to establish tunnel.
4574 MockWrite data_writes1[] = {
4575 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454576 "Host: www.google.com\r\n"
4577 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494578 };
4579
[email protected]77848d12008-11-14 00:00:224580 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494581 // connection. Usually a proxy would return 501 (not implemented),
4582 // or 200 (tunnel established).
4583 MockRead data_reads1[] = {
4584 MockRead("HTTP/1.1 404 Not Found\r\n"),
4585 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064586 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494587 };
4588
[email protected]31a2bfe2010-02-09 08:03:394589 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4590 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074591 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494592
[email protected]49639fa2011-12-20 23:22:414593 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494594
[email protected]49639fa2011-12-20 23:22:414595 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424596 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494597
4598 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424599 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494600
[email protected]1c773ea12009-04-28 19:58:424601 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084602 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494603
[email protected]b4404c02009-04-10 16:38:524604 // Empty the current queue. This is necessary because idle sockets are
4605 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344606 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524607
[email protected]f4e426b2008-11-05 00:24:494608 // We now check to make sure the TCPClientSocket was not added back to
4609 // the pool.
[email protected]90499482013-06-01 00:39:504610 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494611 trans.reset();
[email protected]2da659e2013-05-23 20:51:344612 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494613 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504614 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494615}
[email protected]372d34a2008-11-05 21:30:514616
[email protected]1b157c02009-04-21 01:55:404617// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024618TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424619 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404620 request.method = "GET";
4621 request.url = GURL("http://www.google.com/");
4622 request.load_flags = 0;
4623
[email protected]bb88e1d32013-05-03 23:11:074624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274625
[email protected]262eec82013-03-19 21:01:364626 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274628
[email protected]1b157c02009-04-21 01:55:404629 MockRead data_reads[] = {
4630 // A part of the response body is received with the response headers.
4631 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4632 // The rest of the response body is received in two parts.
4633 MockRead("lo"),
4634 MockRead(" world"),
4635 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064636 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404637 };
4638
[email protected]31a2bfe2010-02-09 08:03:394639 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404641
[email protected]49639fa2011-12-20 23:22:414642 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404643
[email protected]49639fa2011-12-20 23:22:414644 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424645 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404646
4647 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424648 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404649
[email protected]1c773ea12009-04-28 19:58:424650 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504651 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404652
[email protected]90499482013-06-01 00:39:504653 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404654 std::string status_line = response->headers->GetStatusLine();
4655 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4656
[email protected]90499482013-06-01 00:39:504657 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404658
4659 std::string response_data;
4660 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424661 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404662 EXPECT_EQ("hello world", response_data);
4663
4664 // Empty the current queue. This is necessary because idle sockets are
4665 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344666 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404667
4668 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504669 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404670}
4671
[email protected]76a505b2010-08-25 06:23:004672// Make sure that we recycle a SSL socket after reading all of the response
4673// body.
[email protected]23e482282013-06-14 16:08:024674TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004675 HttpRequestInfo request;
4676 request.method = "GET";
4677 request.url = GURL("https://www.google.com/");
4678 request.load_flags = 0;
4679
4680 MockWrite data_writes[] = {
4681 MockWrite("GET / HTTP/1.1\r\n"
4682 "Host: www.google.com\r\n"
4683 "Connection: keep-alive\r\n\r\n"),
4684 };
4685
4686 MockRead data_reads[] = {
4687 MockRead("HTTP/1.1 200 OK\r\n"),
4688 MockRead("Content-Length: 11\r\n\r\n"),
4689 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064690 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004691 };
4692
[email protected]8ddf8322012-02-23 18:08:064693 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074694 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004695
4696 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4697 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074698 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004699
[email protected]49639fa2011-12-20 23:22:414700 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004701
[email protected]bb88e1d32013-05-03 23:11:074702 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[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]76a505b2010-08-25 06:23:004705
[email protected]49639fa2011-12-20 23:22:414706 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004707
4708 EXPECT_EQ(ERR_IO_PENDING, rv);
4709 EXPECT_EQ(OK, callback.WaitForResult());
4710
4711 const HttpResponseInfo* response = trans->GetResponseInfo();
4712 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504713 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004714 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4715
[email protected]90499482013-06-01 00:39:504716 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004717
4718 std::string response_data;
4719 rv = ReadTransaction(trans.get(), &response_data);
4720 EXPECT_EQ(OK, rv);
4721 EXPECT_EQ("hello world", response_data);
4722
4723 // Empty the current queue. This is necessary because idle sockets are
4724 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344725 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004726
4727 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504728 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004729}
4730
4731// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4732// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024733TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004734 HttpRequestInfo request;
4735 request.method = "GET";
4736 request.url = GURL("https://www.google.com/");
4737 request.load_flags = 0;
4738
4739 MockWrite data_writes[] = {
4740 MockWrite("GET / HTTP/1.1\r\n"
4741 "Host: www.google.com\r\n"
4742 "Connection: keep-alive\r\n\r\n"),
4743 MockWrite("GET / HTTP/1.1\r\n"
4744 "Host: www.google.com\r\n"
4745 "Connection: keep-alive\r\n\r\n"),
4746 };
4747
4748 MockRead data_reads[] = {
4749 MockRead("HTTP/1.1 200 OK\r\n"),
4750 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064751 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004752 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064753 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004754 };
4755
[email protected]8ddf8322012-02-23 18:08:064756 SSLSocketDataProvider ssl(ASYNC, OK);
4757 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074758 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004760
4761 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4762 data_writes, arraysize(data_writes));
4763 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4764 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074765 session_deps_.socket_factory->AddSocketDataProvider(&data);
4766 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004767
[email protected]49639fa2011-12-20 23:22:414768 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004769
[email protected]bb88e1d32013-05-03 23:11:074770 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364771 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504772 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004773
[email protected]49639fa2011-12-20 23:22:414774 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004775
4776 EXPECT_EQ(ERR_IO_PENDING, rv);
4777 EXPECT_EQ(OK, callback.WaitForResult());
4778
4779 const HttpResponseInfo* response = trans->GetResponseInfo();
4780 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504781 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004782 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4783
[email protected]90499482013-06-01 00:39:504784 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004785
4786 std::string response_data;
4787 rv = ReadTransaction(trans.get(), &response_data);
4788 EXPECT_EQ(OK, rv);
4789 EXPECT_EQ("hello world", response_data);
4790
4791 // Empty the current queue. This is necessary because idle sockets are
4792 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344793 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004794
4795 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504796 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004797
4798 // Now start the second transaction, which should reuse the previous socket.
4799
[email protected]90499482013-06-01 00:39:504800 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004801
[email protected]49639fa2011-12-20 23:22:414802 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004803
4804 EXPECT_EQ(ERR_IO_PENDING, rv);
4805 EXPECT_EQ(OK, callback.WaitForResult());
4806
4807 response = trans->GetResponseInfo();
4808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504809 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4811
[email protected]90499482013-06-01 00:39:504812 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004813
4814 rv = ReadTransaction(trans.get(), &response_data);
4815 EXPECT_EQ(OK, rv);
4816 EXPECT_EQ("hello world", response_data);
4817
4818 // Empty the current queue. This is necessary because idle sockets are
4819 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344820 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004821
4822 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504823 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004824}
4825
[email protected]b4404c02009-04-10 16:38:524826// Make sure that we recycle a socket after a zero-length response.
4827// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024828TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424829 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524830 request.method = "GET";
4831 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4832 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4833 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4834 "rt=prt.2642,ol.2649,xjs.2951");
4835 request.load_flags = 0;
4836
[email protected]bb88e1d32013-05-03 23:11:074837 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274838
[email protected]262eec82013-03-19 21:01:364839 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504840 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274841
[email protected]b4404c02009-04-10 16:38:524842 MockRead data_reads[] = {
4843 MockRead("HTTP/1.1 204 No Content\r\n"
4844 "Content-Length: 0\r\n"
4845 "Content-Type: text/html\r\n\r\n"),
4846 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064847 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524848 };
4849
[email protected]31a2bfe2010-02-09 08:03:394850 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074851 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524852
[email protected]49639fa2011-12-20 23:22:414853 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524854
[email protected]49639fa2011-12-20 23:22:414855 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424856 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524857
4858 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424859 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524860
[email protected]1c773ea12009-04-28 19:58:424861 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504862 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524863
[email protected]90499482013-06-01 00:39:504864 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524865 std::string status_line = response->headers->GetStatusLine();
4866 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4867
[email protected]90499482013-06-01 00:39:504868 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524869
4870 std::string response_data;
4871 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424872 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524873 EXPECT_EQ("", response_data);
4874
4875 // Empty the current queue. This is necessary because idle sockets are
4876 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344877 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524878
4879 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504880 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524881}
4882
[email protected]23e482282013-06-14 16:08:024883TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064884 ScopedVector<UploadElementReader> element_readers;
4885 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204886 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274887
[email protected]1c773ea12009-04-28 19:58:424888 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514889 // Transaction 1: a GET request that succeeds. The socket is recycled
4890 // after use.
4891 request[0].method = "GET";
4892 request[0].url = GURL("http://www.google.com/");
4893 request[0].load_flags = 0;
4894 // Transaction 2: a POST request. Reuses the socket kept alive from
4895 // transaction 1. The first attempts fails when writing the POST data.
4896 // This causes the transaction to retry with a new socket. The second
4897 // attempt succeeds.
4898 request[1].method = "POST";
4899 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274900 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514901 request[1].load_flags = 0;
4902
[email protected]bb88e1d32013-05-03 23:11:074903 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514904
4905 // The first socket is used for transaction 1 and the first attempt of
4906 // transaction 2.
4907
4908 // The response of transaction 1.
4909 MockRead data_reads1[] = {
4910 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4911 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064912 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514913 };
4914 // The mock write results of transaction 1 and the first attempt of
4915 // transaction 2.
4916 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064917 MockWrite(SYNCHRONOUS, 64), // GET
4918 MockWrite(SYNCHRONOUS, 93), // POST
4919 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514920 };
[email protected]31a2bfe2010-02-09 08:03:394921 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4922 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514923
4924 // The second socket is used for the second attempt of transaction 2.
4925
4926 // The response of transaction 2.
4927 MockRead data_reads2[] = {
4928 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4929 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064930 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514931 };
4932 // The mock write results of the second attempt of transaction 2.
4933 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064934 MockWrite(SYNCHRONOUS, 93), // POST
4935 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514936 };
[email protected]31a2bfe2010-02-09 08:03:394937 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4938 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514939
[email protected]bb88e1d32013-05-03 23:11:074940 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4941 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514942
4943 const char* kExpectedResponseData[] = {
4944 "hello world", "welcome"
4945 };
4946
4947 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424948 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504949 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514950
[email protected]49639fa2011-12-20 23:22:414951 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514952
[email protected]49639fa2011-12-20 23:22:414953 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424954 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514955
4956 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424957 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514958
[email protected]1c773ea12009-04-28 19:58:424959 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504960 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514961
[email protected]90499482013-06-01 00:39:504962 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514963 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4964
4965 std::string response_data;
4966 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424967 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514968 EXPECT_EQ(kExpectedResponseData[i], response_data);
4969 }
4970}
[email protected]f9ee6b52008-11-08 06:46:234971
4972// Test the request-challenge-retry sequence for basic auth when there is
4973// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164974// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024975TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424976 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234977 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294978 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414979 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294980
[email protected]3fe8d2f82013-10-17 08:56:074981 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274982 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074983 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274984
[email protected]a97cca42009-08-14 01:00:294985 // The password contains an escaped character -- for this test to pass it
4986 // will need to be unescaped by HttpNetworkTransaction.
4987 EXPECT_EQ("b%40r", request.url.password());
4988
[email protected]f9ee6b52008-11-08 06:46:234989 MockWrite data_writes1[] = {
4990 MockWrite("GET / HTTP/1.1\r\n"
4991 "Host: www.google.com\r\n"
4992 "Connection: keep-alive\r\n\r\n"),
4993 };
4994
4995 MockRead data_reads1[] = {
4996 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4997 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4998 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064999 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235000 };
5001
[email protected]2262e3a2012-05-22 16:08:165002 // After the challenge above, the transaction will be restarted using the
5003 // identity from the url (foo, b@r) to answer the challenge.
5004 MockWrite data_writes2[] = {
5005 MockWrite("GET / HTTP/1.1\r\n"
5006 "Host: www.google.com\r\n"
5007 "Connection: keep-alive\r\n"
5008 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5009 };
5010
5011 MockRead data_reads2[] = {
5012 MockRead("HTTP/1.0 200 OK\r\n"),
5013 MockRead("Content-Length: 100\r\n\r\n"),
5014 MockRead(SYNCHRONOUS, OK),
5015 };
5016
[email protected]31a2bfe2010-02-09 08:03:395017 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5018 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165019 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5020 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075021 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5022 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235023
[email protected]49639fa2011-12-20 23:22:415024 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415025 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425026 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235027 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425028 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165029 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5030
5031 TestCompletionCallback callback2;
5032 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5033 EXPECT_EQ(ERR_IO_PENDING, rv);
5034 rv = callback2.WaitForResult();
5035 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225036 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5037
[email protected]2262e3a2012-05-22 16:08:165038 const HttpResponseInfo* response = trans->GetResponseInfo();
5039 ASSERT_TRUE(response != NULL);
5040
5041 // There is no challenge info, since the identity in URL worked.
5042 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5043
5044 EXPECT_EQ(100, response->headers->GetContentLength());
5045
5046 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345047 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165048}
5049
5050// Test the request-challenge-retry sequence for basic auth when there is an
5051// incorrect identity in the URL. The identity from the URL should be used only
5052// once.
[email protected]23e482282013-06-14 16:08:025053TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165054 HttpRequestInfo request;
5055 request.method = "GET";
5056 // Note: the URL has a username:password in it. The password "baz" is
5057 // wrong (should be "bar").
5058 request.url = GURL("http://foo:[email protected]/");
5059
5060 request.load_flags = LOAD_NORMAL;
5061
[email protected]3fe8d2f82013-10-17 08:56:075062 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165063 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:165065
5066 MockWrite data_writes1[] = {
5067 MockWrite("GET / HTTP/1.1\r\n"
5068 "Host: www.google.com\r\n"
5069 "Connection: keep-alive\r\n\r\n"),
5070 };
5071
5072 MockRead data_reads1[] = {
5073 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5074 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5075 MockRead("Content-Length: 10\r\n\r\n"),
5076 MockRead(SYNCHRONOUS, ERR_FAILED),
5077 };
5078
5079 // After the challenge above, the transaction will be restarted using the
5080 // identity from the url (foo, baz) to answer the challenge.
5081 MockWrite data_writes2[] = {
5082 MockWrite("GET / HTTP/1.1\r\n"
5083 "Host: www.google.com\r\n"
5084 "Connection: keep-alive\r\n"
5085 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5086 };
5087
5088 MockRead data_reads2[] = {
5089 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5090 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5091 MockRead("Content-Length: 10\r\n\r\n"),
5092 MockRead(SYNCHRONOUS, ERR_FAILED),
5093 };
5094
5095 // After the challenge above, the transaction will be restarted using the
5096 // identity supplied by the user (foo, bar) to answer the challenge.
5097 MockWrite data_writes3[] = {
5098 MockWrite("GET / HTTP/1.1\r\n"
5099 "Host: www.google.com\r\n"
5100 "Connection: keep-alive\r\n"
5101 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5102 };
5103
5104 MockRead data_reads3[] = {
5105 MockRead("HTTP/1.0 200 OK\r\n"),
5106 MockRead("Content-Length: 100\r\n\r\n"),
5107 MockRead(SYNCHRONOUS, OK),
5108 };
5109
5110 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5111 data_writes1, arraysize(data_writes1));
5112 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5113 data_writes2, arraysize(data_writes2));
5114 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5115 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075116 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5117 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5118 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165119
5120 TestCompletionCallback callback1;
5121
5122 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5123 EXPECT_EQ(ERR_IO_PENDING, rv);
5124
5125 rv = callback1.WaitForResult();
5126 EXPECT_EQ(OK, rv);
5127
5128 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5129 TestCompletionCallback callback2;
5130 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5131 EXPECT_EQ(ERR_IO_PENDING, rv);
5132 rv = callback2.WaitForResult();
5133 EXPECT_EQ(OK, rv);
5134 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5135
5136 const HttpResponseInfo* response = trans->GetResponseInfo();
5137 ASSERT_TRUE(response != NULL);
5138 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5139
5140 TestCompletionCallback callback3;
5141 rv = trans->RestartWithAuth(
5142 AuthCredentials(kFoo, kBar), callback3.callback());
5143 EXPECT_EQ(ERR_IO_PENDING, rv);
5144 rv = callback3.WaitForResult();
5145 EXPECT_EQ(OK, rv);
5146 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5147
5148 response = trans->GetResponseInfo();
5149 ASSERT_TRUE(response != NULL);
5150
5151 // There is no challenge info, since the identity worked.
5152 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5153
5154 EXPECT_EQ(100, response->headers->GetContentLength());
5155
[email protected]ea9dc9a2009-09-05 00:43:325156 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345157 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325158}
5159
[email protected]2217aa22013-10-11 03:03:545160
5161// Test the request-challenge-retry sequence for basic auth when there is a
5162// correct identity in the URL, but its use is being suppressed. The identity
5163// from the URL should never be used.
5164TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5165 HttpRequestInfo request;
5166 request.method = "GET";
5167 request.url = GURL("http://foo:[email protected]/");
5168 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5169
[email protected]3fe8d2f82013-10-17 08:56:075170 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545171 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075172 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:545173
5174 MockWrite data_writes1[] = {
5175 MockWrite("GET / HTTP/1.1\r\n"
5176 "Host: www.google.com\r\n"
5177 "Connection: keep-alive\r\n\r\n"),
5178 };
5179
5180 MockRead data_reads1[] = {
5181 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5182 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5183 MockRead("Content-Length: 10\r\n\r\n"),
5184 MockRead(SYNCHRONOUS, ERR_FAILED),
5185 };
5186
5187 // After the challenge above, the transaction will be restarted using the
5188 // identity supplied by the user, not the one in the URL, to answer the
5189 // challenge.
5190 MockWrite data_writes3[] = {
5191 MockWrite("GET / HTTP/1.1\r\n"
5192 "Host: www.google.com\r\n"
5193 "Connection: keep-alive\r\n"
5194 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5195 };
5196
5197 MockRead data_reads3[] = {
5198 MockRead("HTTP/1.0 200 OK\r\n"),
5199 MockRead("Content-Length: 100\r\n\r\n"),
5200 MockRead(SYNCHRONOUS, OK),
5201 };
5202
5203 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5204 data_writes1, arraysize(data_writes1));
5205 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5206 data_writes3, arraysize(data_writes3));
5207 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5208 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5209
5210 TestCompletionCallback callback1;
5211 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5212 EXPECT_EQ(ERR_IO_PENDING, rv);
5213 rv = callback1.WaitForResult();
5214 EXPECT_EQ(OK, rv);
5215 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5216
5217 const HttpResponseInfo* response = trans->GetResponseInfo();
5218 ASSERT_TRUE(response != NULL);
5219 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5220
5221 TestCompletionCallback callback3;
5222 rv = trans->RestartWithAuth(
5223 AuthCredentials(kFoo, kBar), callback3.callback());
5224 EXPECT_EQ(ERR_IO_PENDING, rv);
5225 rv = callback3.WaitForResult();
5226 EXPECT_EQ(OK, rv);
5227 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5228
5229 response = trans->GetResponseInfo();
5230 ASSERT_TRUE(response != NULL);
5231
5232 // There is no challenge info, since the identity worked.
5233 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5234 EXPECT_EQ(100, response->headers->GetContentLength());
5235
5236 // Empty the current queue.
5237 base::MessageLoop::current()->RunUntilIdle();
5238}
5239
[email protected]f9ee6b52008-11-08 06:46:235240// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025241TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075242 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235243
5244 // Transaction 1: authenticate (foo, bar) on MyRealm1
5245 {
[email protected]1c773ea12009-04-28 19:58:425246 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235247 request.method = "GET";
5248 request.url = GURL("http://www.google.com/x/y/z");
5249 request.load_flags = 0;
5250
[email protected]262eec82013-03-19 21:01:365251 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275253
[email protected]f9ee6b52008-11-08 06:46:235254 MockWrite data_writes1[] = {
5255 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5256 "Host: www.google.com\r\n"
5257 "Connection: keep-alive\r\n\r\n"),
5258 };
5259
5260 MockRead data_reads1[] = {
5261 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5262 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5263 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065264 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235265 };
5266
5267 // Resend with authorization (username=foo, password=bar)
5268 MockWrite data_writes2[] = {
5269 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5270 "Host: www.google.com\r\n"
5271 "Connection: keep-alive\r\n"
5272 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5273 };
5274
5275 // Sever accepts the authorization.
5276 MockRead data_reads2[] = {
5277 MockRead("HTTP/1.0 200 OK\r\n"),
5278 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065279 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235280 };
5281
[email protected]31a2bfe2010-02-09 08:03:395282 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5283 data_writes1, arraysize(data_writes1));
5284 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5285 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075286 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5287 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235288
[email protected]49639fa2011-12-20 23:22:415289 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235290
[email protected]49639fa2011-12-20 23:22:415291 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425292 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235293
5294 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425295 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235296
[email protected]1c773ea12009-04-28 19:58:425297 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505298 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045299 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235300
[email protected]49639fa2011-12-20 23:22:415301 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235302
[email protected]49639fa2011-12-20 23:22:415303 rv = trans->RestartWithAuth(
5304 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425305 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235306
5307 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425308 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235309
5310 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505311 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235312 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5313 EXPECT_EQ(100, response->headers->GetContentLength());
5314 }
5315
5316 // ------------------------------------------------------------------------
5317
5318 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5319 {
[email protected]1c773ea12009-04-28 19:58:425320 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235321 request.method = "GET";
5322 // Note that Transaction 1 was at /x/y/z, so this is in the same
5323 // protection space as MyRealm1.
5324 request.url = GURL("http://www.google.com/x/y/a/b");
5325 request.load_flags = 0;
5326
[email protected]262eec82013-03-19 21:01:365327 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505328 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275329
[email protected]f9ee6b52008-11-08 06:46:235330 MockWrite data_writes1[] = {
5331 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5332 "Host: www.google.com\r\n"
5333 "Connection: keep-alive\r\n"
5334 // Send preemptive authorization for MyRealm1
5335 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5336 };
5337
5338 // The server didn't like the preemptive authorization, and
5339 // challenges us for a different realm (MyRealm2).
5340 MockRead data_reads1[] = {
5341 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5342 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5343 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065344 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235345 };
5346
5347 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5348 MockWrite data_writes2[] = {
5349 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5350 "Host: www.google.com\r\n"
5351 "Connection: keep-alive\r\n"
5352 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5353 };
5354
5355 // Sever accepts the authorization.
5356 MockRead data_reads2[] = {
5357 MockRead("HTTP/1.0 200 OK\r\n"),
5358 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065359 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235360 };
5361
[email protected]31a2bfe2010-02-09 08:03:395362 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5363 data_writes1, arraysize(data_writes1));
5364 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5365 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075366 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5367 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235368
[email protected]49639fa2011-12-20 23:22:415369 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235370
[email protected]49639fa2011-12-20 23:22:415371 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425372 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235373
5374 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425375 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235376
[email protected]1c773ea12009-04-28 19:58:425377 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505378 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045379 ASSERT_TRUE(response->auth_challenge.get());
5380 EXPECT_FALSE(response->auth_challenge->is_proxy);
5381 EXPECT_EQ("www.google.com:80",
5382 response->auth_challenge->challenger.ToString());
5383 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5384 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235385
[email protected]49639fa2011-12-20 23:22:415386 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235387
[email protected]49639fa2011-12-20 23:22:415388 rv = trans->RestartWithAuth(
5389 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425390 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235391
5392 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425393 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235394
5395 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505396 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235397 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5398 EXPECT_EQ(100, response->headers->GetContentLength());
5399 }
5400
5401 // ------------------------------------------------------------------------
5402
5403 // Transaction 3: Resend a request in MyRealm's protection space --
5404 // succeed with preemptive authorization.
5405 {
[email protected]1c773ea12009-04-28 19:58:425406 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235407 request.method = "GET";
5408 request.url = GURL("http://www.google.com/x/y/z2");
5409 request.load_flags = 0;
5410
[email protected]262eec82013-03-19 21:01:365411 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275413
[email protected]f9ee6b52008-11-08 06:46:235414 MockWrite data_writes1[] = {
5415 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5416 "Host: www.google.com\r\n"
5417 "Connection: keep-alive\r\n"
5418 // The authorization for MyRealm1 gets sent preemptively
5419 // (since the url is in the same protection space)
5420 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5421 };
5422
5423 // Sever accepts the preemptive authorization
5424 MockRead data_reads1[] = {
5425 MockRead("HTTP/1.0 200 OK\r\n"),
5426 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065427 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235428 };
5429
[email protected]31a2bfe2010-02-09 08:03:395430 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5431 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075432 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235433
[email protected]49639fa2011-12-20 23:22:415434 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235435
[email protected]49639fa2011-12-20 23:22:415436 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425437 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235438
5439 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425440 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235441
[email protected]1c773ea12009-04-28 19:58:425442 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505443 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235444
5445 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5446 EXPECT_EQ(100, response->headers->GetContentLength());
5447 }
5448
5449 // ------------------------------------------------------------------------
5450
5451 // Transaction 4: request another URL in MyRealm (however the
5452 // url is not known to belong to the protection space, so no pre-auth).
5453 {
[email protected]1c773ea12009-04-28 19:58:425454 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235455 request.method = "GET";
5456 request.url = GURL("http://www.google.com/x/1");
5457 request.load_flags = 0;
5458
[email protected]262eec82013-03-19 21:01:365459 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505460 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275461
[email protected]f9ee6b52008-11-08 06:46:235462 MockWrite data_writes1[] = {
5463 MockWrite("GET /x/1 HTTP/1.1\r\n"
5464 "Host: www.google.com\r\n"
5465 "Connection: keep-alive\r\n\r\n"),
5466 };
5467
5468 MockRead data_reads1[] = {
5469 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5470 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5471 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065472 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235473 };
5474
5475 // Resend with authorization from MyRealm's cache.
5476 MockWrite data_writes2[] = {
5477 MockWrite("GET /x/1 HTTP/1.1\r\n"
5478 "Host: www.google.com\r\n"
5479 "Connection: keep-alive\r\n"
5480 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5481 };
5482
5483 // Sever accepts the authorization.
5484 MockRead data_reads2[] = {
5485 MockRead("HTTP/1.0 200 OK\r\n"),
5486 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065487 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235488 };
5489
[email protected]31a2bfe2010-02-09 08:03:395490 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5491 data_writes1, arraysize(data_writes1));
5492 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5493 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075494 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5495 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235496
[email protected]49639fa2011-12-20 23:22:415497 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235498
[email protected]49639fa2011-12-20 23:22:415499 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425500 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235501
5502 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425503 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235504
[email protected]0757e7702009-03-27 04:00:225505 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415506 TestCompletionCallback callback2;
5507 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425508 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225509 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425510 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225511 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5512
[email protected]1c773ea12009-04-28 19:58:425513 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505514 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235515 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5516 EXPECT_EQ(100, response->headers->GetContentLength());
5517 }
5518
5519 // ------------------------------------------------------------------------
5520
5521 // Transaction 5: request a URL in MyRealm, but the server rejects the
5522 // cached identity. Should invalidate and re-prompt.
5523 {
[email protected]1c773ea12009-04-28 19:58:425524 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235525 request.method = "GET";
5526 request.url = GURL("http://www.google.com/p/q/t");
5527 request.load_flags = 0;
5528
[email protected]262eec82013-03-19 21:01:365529 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505530 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275531
[email protected]f9ee6b52008-11-08 06:46:235532 MockWrite data_writes1[] = {
5533 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5534 "Host: www.google.com\r\n"
5535 "Connection: keep-alive\r\n\r\n"),
5536 };
5537
5538 MockRead data_reads1[] = {
5539 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5540 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5541 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065542 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235543 };
5544
5545 // Resend with authorization from cache for MyRealm.
5546 MockWrite data_writes2[] = {
5547 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5548 "Host: www.google.com\r\n"
5549 "Connection: keep-alive\r\n"
5550 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5551 };
5552
5553 // Sever rejects the authorization.
5554 MockRead data_reads2[] = {
5555 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5556 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5557 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065558 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235559 };
5560
5561 // At this point we should prompt for new credentials for MyRealm.
5562 // Restart with username=foo3, password=foo4.
5563 MockWrite data_writes3[] = {
5564 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5565 "Host: www.google.com\r\n"
5566 "Connection: keep-alive\r\n"
5567 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5568 };
5569
5570 // Sever accepts the authorization.
5571 MockRead data_reads3[] = {
5572 MockRead("HTTP/1.0 200 OK\r\n"),
5573 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065574 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235575 };
5576
[email protected]31a2bfe2010-02-09 08:03:395577 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5578 data_writes1, arraysize(data_writes1));
5579 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5580 data_writes2, arraysize(data_writes2));
5581 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5582 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075583 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5584 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5585 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235586
[email protected]49639fa2011-12-20 23:22:415587 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235588
[email protected]49639fa2011-12-20 23:22:415589 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425590 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235591
5592 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425593 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235594
[email protected]0757e7702009-03-27 04:00:225595 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415596 TestCompletionCallback callback2;
5597 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425598 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225599 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425600 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225601 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5602
[email protected]1c773ea12009-04-28 19:58:425603 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505604 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045605 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235606
[email protected]49639fa2011-12-20 23:22:415607 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235608
[email protected]49639fa2011-12-20 23:22:415609 rv = trans->RestartWithAuth(
5610 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425611 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235612
[email protected]0757e7702009-03-27 04:00:225613 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425614 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235615
5616 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505617 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235618 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5619 EXPECT_EQ(100, response->headers->GetContentLength());
5620 }
5621}
[email protected]89ceba9a2009-03-21 03:46:065622
[email protected]3c32c5f2010-05-18 15:18:125623// Tests that nonce count increments when multiple auth attempts
5624// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025625TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445626 HttpAuthHandlerDigest::Factory* digest_factory =
5627 new HttpAuthHandlerDigest::Factory();
5628 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5629 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5630 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075631 session_deps_.http_auth_handler_factory.reset(digest_factory);
5632 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125633
5634 // Transaction 1: authenticate (foo, bar) on MyRealm1
5635 {
[email protected]3c32c5f2010-05-18 15:18:125636 HttpRequestInfo request;
5637 request.method = "GET";
5638 request.url = GURL("http://www.google.com/x/y/z");
5639 request.load_flags = 0;
5640
[email protected]262eec82013-03-19 21:01:365641 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505642 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275643
[email protected]3c32c5f2010-05-18 15:18:125644 MockWrite data_writes1[] = {
5645 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5646 "Host: www.google.com\r\n"
5647 "Connection: keep-alive\r\n\r\n"),
5648 };
5649
5650 MockRead data_reads1[] = {
5651 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5652 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5653 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065654 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125655 };
5656
5657 // Resend with authorization (username=foo, password=bar)
5658 MockWrite data_writes2[] = {
5659 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5660 "Host: www.google.com\r\n"
5661 "Connection: keep-alive\r\n"
5662 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5663 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5664 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5665 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5666 };
5667
5668 // Sever accepts the authorization.
5669 MockRead data_reads2[] = {
5670 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065671 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125672 };
5673
5674 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5675 data_writes1, arraysize(data_writes1));
5676 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5677 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075678 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5679 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125680
[email protected]49639fa2011-12-20 23:22:415681 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125682
[email protected]49639fa2011-12-20 23:22:415683 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125684 EXPECT_EQ(ERR_IO_PENDING, rv);
5685
5686 rv = callback1.WaitForResult();
5687 EXPECT_EQ(OK, rv);
5688
5689 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505690 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045691 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125692
[email protected]49639fa2011-12-20 23:22:415693 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125694
[email protected]49639fa2011-12-20 23:22:415695 rv = trans->RestartWithAuth(
5696 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125697 EXPECT_EQ(ERR_IO_PENDING, rv);
5698
5699 rv = callback2.WaitForResult();
5700 EXPECT_EQ(OK, rv);
5701
5702 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505703 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125704 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5705 }
5706
5707 // ------------------------------------------------------------------------
5708
5709 // Transaction 2: Request another resource in digestive's protection space.
5710 // This will preemptively add an Authorization header which should have an
5711 // "nc" value of 2 (as compared to 1 in the first use.
5712 {
[email protected]3c32c5f2010-05-18 15:18:125713 HttpRequestInfo request;
5714 request.method = "GET";
5715 // Note that Transaction 1 was at /x/y/z, so this is in the same
5716 // protection space as digest.
5717 request.url = GURL("http://www.google.com/x/y/a/b");
5718 request.load_flags = 0;
5719
[email protected]262eec82013-03-19 21:01:365720 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505721 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275722
[email protected]3c32c5f2010-05-18 15:18:125723 MockWrite data_writes1[] = {
5724 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5725 "Host: www.google.com\r\n"
5726 "Connection: keep-alive\r\n"
5727 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5728 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5729 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5730 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5731 };
5732
5733 // Sever accepts the authorization.
5734 MockRead data_reads1[] = {
5735 MockRead("HTTP/1.0 200 OK\r\n"),
5736 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065737 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125738 };
5739
5740 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5741 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075742 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125743
[email protected]49639fa2011-12-20 23:22:415744 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125745
[email protected]49639fa2011-12-20 23:22:415746 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125747 EXPECT_EQ(ERR_IO_PENDING, rv);
5748
5749 rv = callback1.WaitForResult();
5750 EXPECT_EQ(OK, rv);
5751
5752 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505753 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125754 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5755 }
5756}
5757
[email protected]89ceba9a2009-03-21 03:46:065758// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025759TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065760 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075761 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405762 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075763 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065764
5765 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065766 trans->read_buf_ = new IOBuffer(15);
5767 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205768 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065769
5770 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145771 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575772 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085773 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575774 response->response_time = base::Time::Now();
5775 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065776
5777 { // Setup state for response_.vary_data
5778 HttpRequestInfo request;
5779 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5780 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275781 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435782 request.extra_headers.SetHeader("Foo", "1");
5783 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505784 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065785 }
5786
5787 // Cause the above state to be reset.
5788 trans->ResetStateForRestart();
5789
5790 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075791 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065792 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205793 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575794 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5795 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045796 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085797 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575798 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065799}
5800
[email protected]bacff652009-03-31 17:50:335801// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025802TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335803 HttpRequestInfo request;
5804 request.method = "GET";
5805 request.url = GURL("https://www.google.com/");
5806 request.load_flags = 0;
5807
[email protected]3fe8d2f82013-10-17 08:56:075808 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275809 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275811
[email protected]bacff652009-03-31 17:50:335812 MockWrite data_writes[] = {
5813 MockWrite("GET / HTTP/1.1\r\n"
5814 "Host: www.google.com\r\n"
5815 "Connection: keep-alive\r\n\r\n"),
5816 };
5817
5818 MockRead data_reads[] = {
5819 MockRead("HTTP/1.0 200 OK\r\n"),
5820 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5821 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065822 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335823 };
5824
[email protected]5ecc992a42009-11-11 01:41:595825 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395826 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5827 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065828 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5829 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335830
[email protected]bb88e1d32013-05-03 23:11:075831 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5832 session_deps_.socket_factory->AddSocketDataProvider(&data);
5833 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5834 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335835
[email protected]49639fa2011-12-20 23:22:415836 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335837
[email protected]49639fa2011-12-20 23:22:415838 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335839 EXPECT_EQ(ERR_IO_PENDING, rv);
5840
5841 rv = callback.WaitForResult();
5842 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5843
[email protected]49639fa2011-12-20 23:22:415844 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335845 EXPECT_EQ(ERR_IO_PENDING, rv);
5846
5847 rv = callback.WaitForResult();
5848 EXPECT_EQ(OK, rv);
5849
5850 const HttpResponseInfo* response = trans->GetResponseInfo();
5851
[email protected]fe2255a2011-09-20 19:37:505852 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335853 EXPECT_EQ(100, response->headers->GetContentLength());
5854}
5855
5856// Test HTTPS connections to a site with a bad certificate, going through a
5857// proxy
[email protected]23e482282013-06-14 16:08:025858TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075859 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335860
5861 HttpRequestInfo request;
5862 request.method = "GET";
5863 request.url = GURL("https://www.google.com/");
5864 request.load_flags = 0;
5865
5866 MockWrite proxy_writes[] = {
5867 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455868 "Host: www.google.com\r\n"
5869 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335870 };
5871
5872 MockRead proxy_reads[] = {
5873 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065874 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335875 };
5876
5877 MockWrite data_writes[] = {
5878 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455879 "Host: www.google.com\r\n"
5880 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335881 MockWrite("GET / HTTP/1.1\r\n"
5882 "Host: www.google.com\r\n"
5883 "Connection: keep-alive\r\n\r\n"),
5884 };
5885
5886 MockRead data_reads[] = {
5887 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5888 MockRead("HTTP/1.0 200 OK\r\n"),
5889 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5890 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065891 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335892 };
5893
[email protected]31a2bfe2010-02-09 08:03:395894 StaticSocketDataProvider ssl_bad_certificate(
5895 proxy_reads, arraysize(proxy_reads),
5896 proxy_writes, arraysize(proxy_writes));
5897 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5898 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065899 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5900 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335901
[email protected]bb88e1d32013-05-03 23:11:075902 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5903 session_deps_.socket_factory->AddSocketDataProvider(&data);
5904 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5905 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335906
[email protected]49639fa2011-12-20 23:22:415907 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335908
5909 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075910 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335911
[email protected]3fe8d2f82013-10-17 08:56:075912 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405913 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:335915
[email protected]49639fa2011-12-20 23:22:415916 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335917 EXPECT_EQ(ERR_IO_PENDING, rv);
5918
5919 rv = callback.WaitForResult();
5920 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5921
[email protected]49639fa2011-12-20 23:22:415922 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335923 EXPECT_EQ(ERR_IO_PENDING, rv);
5924
5925 rv = callback.WaitForResult();
5926 EXPECT_EQ(OK, rv);
5927
5928 const HttpResponseInfo* response = trans->GetResponseInfo();
5929
[email protected]fe2255a2011-09-20 19:37:505930 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335931 EXPECT_EQ(100, response->headers->GetContentLength());
5932 }
5933}
5934
[email protected]2df19bb2010-08-25 20:13:465935
5936// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025937TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075938 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205939 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5940 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075941 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465942
5943 HttpRequestInfo request;
5944 request.method = "GET";
5945 request.url = GURL("https://www.google.com/");
5946 request.load_flags = 0;
5947
5948 MockWrite data_writes[] = {
5949 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5950 "Host: www.google.com\r\n"
5951 "Proxy-Connection: keep-alive\r\n\r\n"),
5952 MockWrite("GET / HTTP/1.1\r\n"
5953 "Host: www.google.com\r\n"
5954 "Connection: keep-alive\r\n\r\n"),
5955 };
5956
5957 MockRead data_reads[] = {
5958 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5959 MockRead("HTTP/1.1 200 OK\r\n"),
5960 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5961 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065962 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465963 };
5964
5965 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5966 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065967 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5968 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465969
[email protected]bb88e1d32013-05-03 23:11:075970 session_deps_.socket_factory->AddSocketDataProvider(&data);
5971 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5972 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465973
[email protected]49639fa2011-12-20 23:22:415974 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465975
[email protected]3fe8d2f82013-10-17 08:56:075976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465977 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:465979
[email protected]49639fa2011-12-20 23:22:415980 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465981 EXPECT_EQ(ERR_IO_PENDING, rv);
5982
5983 rv = callback.WaitForResult();
5984 EXPECT_EQ(OK, rv);
5985 const HttpResponseInfo* response = trans->GetResponseInfo();
5986
[email protected]fe2255a2011-09-20 19:37:505987 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465988
5989 EXPECT_TRUE(response->headers->IsKeepAlive());
5990 EXPECT_EQ(200, response->headers->response_code());
5991 EXPECT_EQ(100, response->headers->GetContentLength());
5992 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205993
5994 LoadTimingInfo load_timing_info;
5995 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5996 TestLoadTimingNotReusedWithPac(load_timing_info,
5997 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465998}
5999
[email protected]511f6f52010-12-17 03:58:296000// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026001TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076002 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206003 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6004 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076005 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296006
6007 HttpRequestInfo request;
6008 request.method = "GET";
6009 request.url = GURL("https://www.google.com/");
6010 request.load_flags = 0;
6011
6012 MockWrite data_writes[] = {
6013 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6014 "Host: www.google.com\r\n"
6015 "Proxy-Connection: keep-alive\r\n\r\n"),
6016 };
6017
6018 MockRead data_reads[] = {
6019 MockRead("HTTP/1.1 302 Redirect\r\n"),
6020 MockRead("Location: http://login.example.com/\r\n"),
6021 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066022 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296023 };
6024
6025 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6026 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066027 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296028
[email protected]bb88e1d32013-05-03 23:11:076029 session_deps_.socket_factory->AddSocketDataProvider(&data);
6030 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296031
[email protected]49639fa2011-12-20 23:22:416032 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296033
[email protected]3fe8d2f82013-10-17 08:56:076034 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296035 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076036 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296037
[email protected]49639fa2011-12-20 23:22:416038 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296039 EXPECT_EQ(ERR_IO_PENDING, rv);
6040
6041 rv = callback.WaitForResult();
6042 EXPECT_EQ(OK, rv);
6043 const HttpResponseInfo* response = trans->GetResponseInfo();
6044
[email protected]fe2255a2011-09-20 19:37:506045 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296046
6047 EXPECT_EQ(302, response->headers->response_code());
6048 std::string url;
6049 EXPECT_TRUE(response->headers->IsRedirect(&url));
6050 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206051
6052 // In the case of redirects from proxies, HttpNetworkTransaction returns
6053 // timing for the proxy connection instead of the connection to the host,
6054 // and no send / receive times.
6055 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6056 LoadTimingInfo load_timing_info;
6057 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6058
6059 EXPECT_FALSE(load_timing_info.socket_reused);
6060 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6061
6062 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6063 EXPECT_LE(load_timing_info.proxy_resolve_start,
6064 load_timing_info.proxy_resolve_end);
6065 EXPECT_LE(load_timing_info.proxy_resolve_end,
6066 load_timing_info.connect_timing.connect_start);
6067 ExpectConnectTimingHasTimes(
6068 load_timing_info.connect_timing,
6069 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6070
6071 EXPECT_TRUE(load_timing_info.send_start.is_null());
6072 EXPECT_TRUE(load_timing_info.send_end.is_null());
6073 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296074}
6075
6076// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026077TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076078 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296079 ProxyService::CreateFixed("https://proxy:70"));
6080
6081 HttpRequestInfo request;
6082 request.method = "GET";
6083 request.url = GURL("https://www.google.com/");
6084 request.load_flags = 0;
6085
[email protected]9075f51c2013-08-15 17:53:546086 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6087 LOWEST));
[email protected]c10b20852013-05-15 21:29:206088 scoped_ptr<SpdyFrame> goaway(
6089 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296090 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066091 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126092 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296093 };
6094
6095 static const char* const kExtraHeaders[] = {
6096 "location",
6097 "http://login.example.com/",
6098 };
[email protected]ff98d7f02012-03-22 21:44:196099 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026100 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296101 arraysize(kExtraHeaders)/2, 1));
6102 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066103 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6104 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296105 };
6106
[email protected]dd54bd82012-07-19 23:44:576107 DelayedSocketData data(
6108 1, // wait for one write to finish before reading.
6109 data_reads, arraysize(data_reads),
6110 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066111 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026112 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296113
[email protected]bb88e1d32013-05-03 23:11:076114 session_deps_.socket_factory->AddSocketDataProvider(&data);
6115 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296116
[email protected]49639fa2011-12-20 23:22:416117 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296118
[email protected]3fe8d2f82013-10-17 08:56:076119 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296120 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296122
[email protected]49639fa2011-12-20 23:22:416123 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296124 EXPECT_EQ(ERR_IO_PENDING, rv);
6125
6126 rv = callback.WaitForResult();
6127 EXPECT_EQ(OK, rv);
6128 const HttpResponseInfo* response = trans->GetResponseInfo();
6129
[email protected]fe2255a2011-09-20 19:37:506130 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296131
6132 EXPECT_EQ(302, response->headers->response_code());
6133 std::string url;
6134 EXPECT_TRUE(response->headers->IsRedirect(&url));
6135 EXPECT_EQ("http://login.example.com/", url);
6136}
6137
[email protected]4eddbc732012-08-09 05:40:176138// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026139TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176140 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076141 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296142 ProxyService::CreateFixed("https://proxy:70"));
6143
6144 HttpRequestInfo request;
6145 request.method = "GET";
6146 request.url = GURL("https://www.google.com/");
6147 request.load_flags = 0;
6148
6149 MockWrite data_writes[] = {
6150 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6151 "Host: www.google.com\r\n"
6152 "Proxy-Connection: keep-alive\r\n\r\n"),
6153 };
6154
6155 MockRead data_reads[] = {
6156 MockRead("HTTP/1.1 404 Not Found\r\n"),
6157 MockRead("Content-Length: 23\r\n\r\n"),
6158 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066159 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296160 };
6161
6162 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6163 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066164 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296165
[email protected]bb88e1d32013-05-03 23:11:076166 session_deps_.socket_factory->AddSocketDataProvider(&data);
6167 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296168
[email protected]49639fa2011-12-20 23:22:416169 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296170
[email protected]3fe8d2f82013-10-17 08:56:076171 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296172 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076173 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296174
[email protected]49639fa2011-12-20 23:22:416175 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296176 EXPECT_EQ(ERR_IO_PENDING, rv);
6177
6178 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176179 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296180
[email protected]4eddbc732012-08-09 05:40:176181 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296182}
6183
[email protected]4eddbc732012-08-09 05:40:176184// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026185TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176186 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076187 session_deps_.proxy_service.reset(
6188 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296189
6190 HttpRequestInfo request;
6191 request.method = "GET";
6192 request.url = GURL("https://www.google.com/");
6193 request.load_flags = 0;
6194
[email protected]9075f51c2013-08-15 17:53:546195 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6196 LOWEST));
[email protected]c10b20852013-05-15 21:29:206197 scoped_ptr<SpdyFrame> rst(
6198 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296199 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066200 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176201 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296202 };
6203
6204 static const char* const kExtraHeaders[] = {
6205 "location",
6206 "http://login.example.com/",
6207 };
[email protected]ff98d7f02012-03-22 21:44:196208 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026209 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296210 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196211 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026212 spdy_util_.ConstructSpdyBodyFrame(
6213 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296214 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066215 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6216 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176217 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296218 };
6219
[email protected]dd54bd82012-07-19 23:44:576220 DelayedSocketData data(
6221 1, // wait for one write to finish before reading.
6222 data_reads, arraysize(data_reads),
6223 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066224 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026225 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296226
[email protected]bb88e1d32013-05-03 23:11:076227 session_deps_.socket_factory->AddSocketDataProvider(&data);
6228 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296229
[email protected]49639fa2011-12-20 23:22:416230 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296231
[email protected]3fe8d2f82013-10-17 08:56:076232 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296233 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076234 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296235
[email protected]49639fa2011-12-20 23:22:416236 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296237 EXPECT_EQ(ERR_IO_PENDING, rv);
6238
6239 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176240 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296241
[email protected]4eddbc732012-08-09 05:40:176242 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296243}
6244
[email protected]0c5fb722012-02-28 11:50:356245// Test the request-challenge-retry sequence for basic auth, through
6246// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026247TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356248 HttpRequestInfo request;
6249 request.method = "GET";
6250 request.url = GURL("https://www.google.com/");
6251 // when the no authentication data flag is set.
6252 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6253
6254 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076255 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206256 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296257 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076258 session_deps_.net_log = log.bound().net_log();
6259 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356260
6261 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:546262 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6263 LOWEST));
[email protected]c10b20852013-05-15 21:29:206264 scoped_ptr<SpdyFrame> rst(
6265 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356266
6267 // After calling trans->RestartWithAuth(), this is the request we should
6268 // be issuing -- the final header line contains the credentials.
6269 const char* const kAuthCredentials[] = {
6270 "proxy-authorization", "Basic Zm9vOmJhcg==",
6271 };
[email protected]fba2dbde2013-05-24 16:09:016272 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:546273 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:356274 // fetch https://www.google.com/ via HTTP
6275 const char get[] = "GET / HTTP/1.1\r\n"
6276 "Host: www.google.com\r\n"
6277 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196278 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026279 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356280
6281 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206282 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216283 CreateMockWrite(*rst, 4, ASYNC),
6284 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206285 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356286 };
6287
6288 // The proxy responds to the connect with a 407, using a persistent
6289 // connection.
6290 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:026291 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
6292 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:356293 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6294 };
6295
[email protected]ff98d7f02012-03-22 21:44:196296 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:236297 spdy_util_.ConstructSpdyControlFrame(NULL,
6298 0,
6299 false,
6300 1,
6301 LOWEST,
6302 SYN_REPLY,
6303 CONTROL_FLAG_NONE,
6304 kAuthChallenge,
6305 arraysize(kAuthChallenge),
6306 0));
[email protected]0c5fb722012-02-28 11:50:356307
[email protected]23e482282013-06-14 16:08:026308 scoped_ptr<SpdyFrame> conn_resp(
6309 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356310 const char resp[] = "HTTP/1.1 200 OK\r\n"
6311 "Content-Length: 5\r\n\r\n";
6312
[email protected]ff98d7f02012-03-22 21:44:196313 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026314 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196315 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026316 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356317 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206318 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6319 CreateMockRead(*conn_resp, 6, ASYNC),
6320 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6321 CreateMockRead(*wrapped_body, 10, ASYNC),
6322 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356323 };
6324
[email protected]dd54bd82012-07-19 23:44:576325 OrderedSocketData spdy_data(
6326 spdy_reads, arraysize(spdy_reads),
6327 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076328 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356329 // Negotiate SPDY to the proxy
6330 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026331 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076332 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356333 // Vanilla SSL to the server
6334 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076335 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356336
6337 TestCompletionCallback callback1;
6338
[email protected]262eec82013-03-19 21:01:366339 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506340 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356341
6342 int rv = trans->Start(&request, callback1.callback(), log.bound());
6343 EXPECT_EQ(ERR_IO_PENDING, rv);
6344
6345 rv = callback1.WaitForResult();
6346 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576347 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356348 log.GetEntries(&entries);
6349 size_t pos = ExpectLogContainsSomewhere(
6350 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6351 NetLog::PHASE_NONE);
6352 ExpectLogContainsSomewhere(
6353 entries, pos,
6354 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6355 NetLog::PHASE_NONE);
6356
6357 const HttpResponseInfo* response = trans->GetResponseInfo();
6358 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506359 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356360 EXPECT_EQ(407, response->headers->response_code());
6361 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6362 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6363 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6364
6365 TestCompletionCallback callback2;
6366
6367 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6368 callback2.callback());
6369 EXPECT_EQ(ERR_IO_PENDING, rv);
6370
6371 rv = callback2.WaitForResult();
6372 EXPECT_EQ(OK, rv);
6373
6374 response = trans->GetResponseInfo();
6375 ASSERT_TRUE(response != NULL);
6376
6377 EXPECT_TRUE(response->headers->IsKeepAlive());
6378 EXPECT_EQ(200, response->headers->response_code());
6379 EXPECT_EQ(5, response->headers->GetContentLength());
6380 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6381
6382 // The password prompt info should not be set.
6383 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6384
[email protected]029c83b62013-01-24 05:28:206385 LoadTimingInfo load_timing_info;
6386 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6387 TestLoadTimingNotReusedWithPac(load_timing_info,
6388 CONNECT_TIMING_HAS_SSL_TIMES);
6389
[email protected]0c5fb722012-02-28 11:50:356390 trans.reset();
6391 session->CloseAllConnections();
6392}
6393
[email protected]7c6f7ba2012-04-03 04:09:296394// Test that an explicitly trusted SPDY proxy can push a resource from an
6395// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026396TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296397 HttpRequestInfo request;
6398 HttpRequestInfo push_request;
6399
[email protected]7c6f7ba2012-04-03 04:09:296400 request.method = "GET";
6401 request.url = GURL("http://www.google.com/");
6402 push_request.method = "GET";
6403 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6404
[email protected]7c6f7ba2012-04-03 04:09:296405 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076406 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206407 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296408 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076409 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506410
6411 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076412 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506413
[email protected]bb88e1d32013-05-03 23:11:076414 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296415
[email protected]cdf8f7e72013-05-23 10:56:466416 scoped_ptr<SpdyFrame> stream1_syn(
6417 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296418
6419 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466420 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296421 };
6422
6423 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026424 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296425
6426 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026427 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296428
6429 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026430 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296431 0,
6432 2,
6433 1,
6434 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436435 const char kPushedData[] = "pushed";
6436 scoped_ptr<SpdyFrame> stream2_body(
6437 spdy_util_.ConstructSpdyBodyFrame(
6438 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296439
6440 MockRead spdy_reads[] = {
6441 CreateMockRead(*stream1_reply, 2, ASYNC),
6442 CreateMockRead(*stream2_syn, 3, ASYNC),
6443 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436444 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296445 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6446 };
6447
[email protected]dd54bd82012-07-19 23:44:576448 OrderedSocketData spdy_data(
6449 spdy_reads, arraysize(spdy_reads),
6450 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076451 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296452 // Negotiate SPDY to the proxy
6453 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026454 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076455 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296456
[email protected]262eec82013-03-19 21:01:366457 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506458 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296459 TestCompletionCallback callback;
6460 int rv = trans->Start(&request, callback.callback(), log.bound());
6461 EXPECT_EQ(ERR_IO_PENDING, rv);
6462
6463 rv = callback.WaitForResult();
6464 EXPECT_EQ(OK, rv);
6465 const HttpResponseInfo* response = trans->GetResponseInfo();
6466
[email protected]262eec82013-03-19 21:01:366467 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506468 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6469 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296470 EXPECT_EQ(ERR_IO_PENDING, rv);
6471
6472 rv = callback.WaitForResult();
6473 EXPECT_EQ(OK, rv);
6474 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6475
6476 ASSERT_TRUE(response != NULL);
6477 EXPECT_TRUE(response->headers->IsKeepAlive());
6478
6479 EXPECT_EQ(200, response->headers->response_code());
6480 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6481
6482 std::string response_data;
6483 rv = ReadTransaction(trans.get(), &response_data);
6484 EXPECT_EQ(OK, rv);
6485 EXPECT_EQ("hello!", response_data);
6486
[email protected]029c83b62013-01-24 05:28:206487 LoadTimingInfo load_timing_info;
6488 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6489 TestLoadTimingNotReusedWithPac(load_timing_info,
6490 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6491
[email protected]7c6f7ba2012-04-03 04:09:296492 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506493 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296494 EXPECT_EQ(200, push_response->headers->response_code());
6495
6496 rv = ReadTransaction(push_trans.get(), &response_data);
6497 EXPECT_EQ(OK, rv);
6498 EXPECT_EQ("pushed", response_data);
6499
[email protected]029c83b62013-01-24 05:28:206500 LoadTimingInfo push_load_timing_info;
6501 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6502 TestLoadTimingReusedWithPac(push_load_timing_info);
6503 // The transactions should share a socket ID, despite being for different
6504 // origins.
6505 EXPECT_EQ(load_timing_info.socket_log_id,
6506 push_load_timing_info.socket_log_id);
6507
[email protected]7c6f7ba2012-04-03 04:09:296508 trans.reset();
6509 push_trans.reset();
6510 session->CloseAllConnections();
6511}
6512
[email protected]8c843192012-04-05 07:15:006513// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026514TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006515 HttpRequestInfo request;
6516
6517 request.method = "GET";
6518 request.url = GURL("http://www.google.com/");
6519
[email protected]8c843192012-04-05 07:15:006520 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076521 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006522 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296523 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076524 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506525
6526 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076527 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506528
[email protected]bb88e1d32013-05-03 23:11:076529 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006530
[email protected]cdf8f7e72013-05-23 10:56:466531 scoped_ptr<SpdyFrame> stream1_syn(
6532 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006533
6534 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206535 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006536
6537 MockWrite spdy_writes[] = {
6538 CreateMockWrite(*stream1_syn, 1, ASYNC),
6539 CreateMockWrite(*push_rst, 4),
6540 };
6541
6542 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026543 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006544
6545 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026546 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006547
6548 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026549 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006550 0,
6551 2,
6552 1,
6553 "https://www.another-origin.com/foo.dat"));
6554
6555 MockRead spdy_reads[] = {
6556 CreateMockRead(*stream1_reply, 2, ASYNC),
6557 CreateMockRead(*stream2_syn, 3, ASYNC),
6558 CreateMockRead(*stream1_body, 5, ASYNC),
6559 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6560 };
6561
[email protected]dd54bd82012-07-19 23:44:576562 OrderedSocketData spdy_data(
6563 spdy_reads, arraysize(spdy_reads),
6564 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076565 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006566 // Negotiate SPDY to the proxy
6567 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026568 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076569 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006570
[email protected]262eec82013-03-19 21:01:366571 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506572 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006573 TestCompletionCallback callback;
6574 int rv = trans->Start(&request, callback.callback(), log.bound());
6575 EXPECT_EQ(ERR_IO_PENDING, rv);
6576
6577 rv = callback.WaitForResult();
6578 EXPECT_EQ(OK, rv);
6579 const HttpResponseInfo* response = trans->GetResponseInfo();
6580
6581 ASSERT_TRUE(response != NULL);
6582 EXPECT_TRUE(response->headers->IsKeepAlive());
6583
6584 EXPECT_EQ(200, response->headers->response_code());
6585 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6586
6587 std::string response_data;
6588 rv = ReadTransaction(trans.get(), &response_data);
6589 EXPECT_EQ(OK, rv);
6590 EXPECT_EQ("hello!", response_data);
6591
6592 trans.reset();
6593 session->CloseAllConnections();
6594}
6595
[email protected]2df19bb2010-08-25 20:13:466596// Test HTTPS connections to a site with a bad certificate, going through an
6597// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026598TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076599 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116600 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466601
6602 HttpRequestInfo request;
6603 request.method = "GET";
6604 request.url = GURL("https://www.google.com/");
6605 request.load_flags = 0;
6606
6607 // Attempt to fetch the URL from a server with a bad cert
6608 MockWrite bad_cert_writes[] = {
6609 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6610 "Host: www.google.com\r\n"
6611 "Proxy-Connection: keep-alive\r\n\r\n"),
6612 };
6613
6614 MockRead bad_cert_reads[] = {
6615 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066616 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466617 };
6618
6619 // Attempt to fetch the URL with a good cert
6620 MockWrite good_data_writes[] = {
6621 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6622 "Host: www.google.com\r\n"
6623 "Proxy-Connection: keep-alive\r\n\r\n"),
6624 MockWrite("GET / HTTP/1.1\r\n"
6625 "Host: www.google.com\r\n"
6626 "Connection: keep-alive\r\n\r\n"),
6627 };
6628
6629 MockRead good_cert_reads[] = {
6630 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6631 MockRead("HTTP/1.0 200 OK\r\n"),
6632 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6633 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066634 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466635 };
6636
6637 StaticSocketDataProvider ssl_bad_certificate(
6638 bad_cert_reads, arraysize(bad_cert_reads),
6639 bad_cert_writes, arraysize(bad_cert_writes));
6640 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6641 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066642 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6643 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466644
6645 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076646 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6647 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466649
6650 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076651 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6652 session_deps_.socket_factory->AddSocketDataProvider(&data);
6653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466654
[email protected]49639fa2011-12-20 23:22:416655 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466656
[email protected]3fe8d2f82013-10-17 08:56:076657 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466658 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076659 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466660
[email protected]49639fa2011-12-20 23:22:416661 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466662 EXPECT_EQ(ERR_IO_PENDING, rv);
6663
6664 rv = callback.WaitForResult();
6665 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6666
[email protected]49639fa2011-12-20 23:22:416667 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466668 EXPECT_EQ(ERR_IO_PENDING, rv);
6669
6670 rv = callback.WaitForResult();
6671 EXPECT_EQ(OK, rv);
6672
6673 const HttpResponseInfo* response = trans->GetResponseInfo();
6674
[email protected]fe2255a2011-09-20 19:37:506675 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466676 EXPECT_EQ(100, response->headers->GetContentLength());
6677}
6678
[email protected]23e482282013-06-14 16:08:026679TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426680 HttpRequestInfo request;
6681 request.method = "GET";
6682 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436683 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6684 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426685
[email protected]3fe8d2f82013-10-17 08:56:076686 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276687 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276689
[email protected]1c773ea12009-04-28 19:58:426690 MockWrite data_writes[] = {
6691 MockWrite("GET / HTTP/1.1\r\n"
6692 "Host: www.google.com\r\n"
6693 "Connection: keep-alive\r\n"
6694 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6695 };
6696
6697 // Lastly, the server responds with the actual content.
6698 MockRead data_reads[] = {
6699 MockRead("HTTP/1.0 200 OK\r\n"),
6700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6701 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066702 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426703 };
6704
[email protected]31a2bfe2010-02-09 08:03:396705 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6706 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076707 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426708
[email protected]49639fa2011-12-20 23:22:416709 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426710
[email protected]49639fa2011-12-20 23:22:416711 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426712 EXPECT_EQ(ERR_IO_PENDING, rv);
6713
6714 rv = callback.WaitForResult();
6715 EXPECT_EQ(OK, rv);
6716}
6717
[email protected]23e482282013-06-14 16:08:026718TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296719 HttpRequestInfo request;
6720 request.method = "GET";
6721 request.url = GURL("https://www.google.com/");
6722 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6723 "Chromium Ultra Awesome X Edition");
6724
[email protected]bb88e1d32013-05-03 23:11:076725 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076726 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276727 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076728 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276729
[email protected]da81f132010-08-18 23:39:296730 MockWrite data_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"
6734 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6735 };
6736 MockRead data_reads[] = {
6737 // Return an error, so the transaction stops here (this test isn't
6738 // interested in the rest).
6739 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6740 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6741 MockRead("Proxy-Connection: close\r\n\r\n"),
6742 };
6743
6744 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6745 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076746 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296747
[email protected]49639fa2011-12-20 23:22:416748 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296749
[email protected]49639fa2011-12-20 23:22:416750 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296751 EXPECT_EQ(ERR_IO_PENDING, rv);
6752
6753 rv = callback.WaitForResult();
6754 EXPECT_EQ(OK, rv);
6755}
6756
[email protected]23e482282013-06-14 16:08:026757TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426758 HttpRequestInfo request;
6759 request.method = "GET";
6760 request.url = GURL("http://www.google.com/");
6761 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166762 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6763 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426764
[email protected]3fe8d2f82013-10-17 08:56:076765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276766 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076767 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276768
[email protected]1c773ea12009-04-28 19:58:426769 MockWrite data_writes[] = {
6770 MockWrite("GET / HTTP/1.1\r\n"
6771 "Host: www.google.com\r\n"
6772 "Connection: keep-alive\r\n"
6773 "Referer: http://the.previous.site.com/\r\n\r\n"),
6774 };
6775
6776 // Lastly, the server responds with the actual content.
6777 MockRead data_reads[] = {
6778 MockRead("HTTP/1.0 200 OK\r\n"),
6779 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6780 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066781 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426782 };
6783
[email protected]31a2bfe2010-02-09 08:03:396784 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6785 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076786 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426787
[email protected]49639fa2011-12-20 23:22:416788 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426789
[email protected]49639fa2011-12-20 23:22:416790 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426791 EXPECT_EQ(ERR_IO_PENDING, rv);
6792
6793 rv = callback.WaitForResult();
6794 EXPECT_EQ(OK, rv);
6795}
6796
[email protected]23e482282013-06-14 16:08:026797TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426798 HttpRequestInfo request;
6799 request.method = "POST";
6800 request.url = GURL("http://www.google.com/");
6801
[email protected]3fe8d2f82013-10-17 08:56:076802 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276803 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276805
[email protected]1c773ea12009-04-28 19:58:426806 MockWrite data_writes[] = {
6807 MockWrite("POST / HTTP/1.1\r\n"
6808 "Host: www.google.com\r\n"
6809 "Connection: keep-alive\r\n"
6810 "Content-Length: 0\r\n\r\n"),
6811 };
6812
6813 // Lastly, the server responds with the actual content.
6814 MockRead data_reads[] = {
6815 MockRead("HTTP/1.0 200 OK\r\n"),
6816 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6817 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066818 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426819 };
6820
[email protected]31a2bfe2010-02-09 08:03:396821 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6822 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076823 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426824
[email protected]49639fa2011-12-20 23:22:416825 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426826
[email protected]49639fa2011-12-20 23:22:416827 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426828 EXPECT_EQ(ERR_IO_PENDING, rv);
6829
6830 rv = callback.WaitForResult();
6831 EXPECT_EQ(OK, rv);
6832}
6833
[email protected]23e482282013-06-14 16:08:026834TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426835 HttpRequestInfo request;
6836 request.method = "PUT";
6837 request.url = GURL("http://www.google.com/");
6838
[email protected]3fe8d2f82013-10-17 08:56:076839 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276840 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276842
[email protected]1c773ea12009-04-28 19:58:426843 MockWrite data_writes[] = {
6844 MockWrite("PUT / HTTP/1.1\r\n"
6845 "Host: www.google.com\r\n"
6846 "Connection: keep-alive\r\n"
6847 "Content-Length: 0\r\n\r\n"),
6848 };
6849
6850 // Lastly, the server responds with the actual content.
6851 MockRead data_reads[] = {
6852 MockRead("HTTP/1.0 200 OK\r\n"),
6853 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6854 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066855 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426856 };
6857
[email protected]31a2bfe2010-02-09 08:03:396858 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6859 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076860 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426861
[email protected]49639fa2011-12-20 23:22:416862 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426863
[email protected]49639fa2011-12-20 23:22:416864 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426865 EXPECT_EQ(ERR_IO_PENDING, rv);
6866
6867 rv = callback.WaitForResult();
6868 EXPECT_EQ(OK, rv);
6869}
6870
[email protected]23e482282013-06-14 16:08:026871TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426872 HttpRequestInfo request;
6873 request.method = "HEAD";
6874 request.url = GURL("http://www.google.com/");
6875
[email protected]3fe8d2f82013-10-17 08:56:076876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276877 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276879
[email protected]1c773ea12009-04-28 19:58:426880 MockWrite data_writes[] = {
6881 MockWrite("HEAD / HTTP/1.1\r\n"
6882 "Host: www.google.com\r\n"
6883 "Connection: keep-alive\r\n"
6884 "Content-Length: 0\r\n\r\n"),
6885 };
6886
6887 // Lastly, the server responds with the actual content.
6888 MockRead data_reads[] = {
6889 MockRead("HTTP/1.0 200 OK\r\n"),
6890 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6891 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066892 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426893 };
6894
[email protected]31a2bfe2010-02-09 08:03:396895 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6896 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076897 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426898
[email protected]49639fa2011-12-20 23:22:416899 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426900
[email protected]49639fa2011-12-20 23:22:416901 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426902 EXPECT_EQ(ERR_IO_PENDING, rv);
6903
6904 rv = callback.WaitForResult();
6905 EXPECT_EQ(OK, rv);
6906}
6907
[email protected]23e482282013-06-14 16:08:026908TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426909 HttpRequestInfo request;
6910 request.method = "GET";
6911 request.url = GURL("http://www.google.com/");
6912 request.load_flags = LOAD_BYPASS_CACHE;
6913
[email protected]3fe8d2f82013-10-17 08:56:076914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276915 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076916 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276917
[email protected]1c773ea12009-04-28 19:58:426918 MockWrite data_writes[] = {
6919 MockWrite("GET / HTTP/1.1\r\n"
6920 "Host: www.google.com\r\n"
6921 "Connection: keep-alive\r\n"
6922 "Pragma: no-cache\r\n"
6923 "Cache-Control: no-cache\r\n\r\n"),
6924 };
6925
6926 // Lastly, the server responds with the actual content.
6927 MockRead data_reads[] = {
6928 MockRead("HTTP/1.0 200 OK\r\n"),
6929 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6930 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066931 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426932 };
6933
[email protected]31a2bfe2010-02-09 08:03:396934 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6935 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076936 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426937
[email protected]49639fa2011-12-20 23:22:416938 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426939
[email protected]49639fa2011-12-20 23:22:416940 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426941 EXPECT_EQ(ERR_IO_PENDING, rv);
6942
6943 rv = callback.WaitForResult();
6944 EXPECT_EQ(OK, rv);
6945}
6946
[email protected]23e482282013-06-14 16:08:026947TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426948 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426949 HttpRequestInfo request;
6950 request.method = "GET";
6951 request.url = GURL("http://www.google.com/");
6952 request.load_flags = LOAD_VALIDATE_CACHE;
6953
[email protected]3fe8d2f82013-10-17 08:56:076954 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276955 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276957
[email protected]1c773ea12009-04-28 19:58:426958 MockWrite data_writes[] = {
6959 MockWrite("GET / HTTP/1.1\r\n"
6960 "Host: www.google.com\r\n"
6961 "Connection: keep-alive\r\n"
6962 "Cache-Control: max-age=0\r\n\r\n"),
6963 };
6964
6965 // Lastly, the server responds with the actual content.
6966 MockRead data_reads[] = {
6967 MockRead("HTTP/1.0 200 OK\r\n"),
6968 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6969 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066970 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426971 };
6972
[email protected]31a2bfe2010-02-09 08:03:396973 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6974 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076975 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426976
[email protected]49639fa2011-12-20 23:22:416977 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426978
[email protected]49639fa2011-12-20 23:22:416979 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426980 EXPECT_EQ(ERR_IO_PENDING, rv);
6981
6982 rv = callback.WaitForResult();
6983 EXPECT_EQ(OK, rv);
6984}
6985
[email protected]23e482282013-06-14 16:08:026986TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426987 HttpRequestInfo request;
6988 request.method = "GET";
6989 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436990 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426991
[email protected]3fe8d2f82013-10-17 08:56:076992 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276993 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276995
[email protected]1c773ea12009-04-28 19:58:426996 MockWrite data_writes[] = {
6997 MockWrite("GET / HTTP/1.1\r\n"
6998 "Host: www.google.com\r\n"
6999 "Connection: keep-alive\r\n"
7000 "FooHeader: Bar\r\n\r\n"),
7001 };
7002
7003 // Lastly, the server responds with the actual content.
7004 MockRead data_reads[] = {
7005 MockRead("HTTP/1.0 200 OK\r\n"),
7006 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7007 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067008 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427009 };
7010
[email protected]31a2bfe2010-02-09 08:03:397011 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7012 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077013 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427014
[email protected]49639fa2011-12-20 23:22:417015 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427016
[email protected]49639fa2011-12-20 23:22:417017 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427018 EXPECT_EQ(ERR_IO_PENDING, rv);
7019
7020 rv = callback.WaitForResult();
7021 EXPECT_EQ(OK, rv);
7022}
7023
[email protected]23e482282013-06-14 16:08:027024TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477025 HttpRequestInfo request;
7026 request.method = "GET";
7027 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437028 request.extra_headers.SetHeader("referer", "www.foo.com");
7029 request.extra_headers.SetHeader("hEllo", "Kitty");
7030 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477031
[email protected]3fe8d2f82013-10-17 08:56:077032 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277033 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077034 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277035
[email protected]270c6412010-03-29 22:02:477036 MockWrite data_writes[] = {
7037 MockWrite("GET / HTTP/1.1\r\n"
7038 "Host: www.google.com\r\n"
7039 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167040 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477041 "hEllo: Kitty\r\n"
7042 "FoO: bar\r\n\r\n"),
7043 };
7044
7045 // Lastly, the server responds with the actual content.
7046 MockRead data_reads[] = {
7047 MockRead("HTTP/1.0 200 OK\r\n"),
7048 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7049 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067050 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477051 };
7052
7053 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7054 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077055 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477056
[email protected]49639fa2011-12-20 23:22:417057 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477058
[email protected]49639fa2011-12-20 23:22:417059 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477060 EXPECT_EQ(ERR_IO_PENDING, rv);
7061
7062 rv = callback.WaitForResult();
7063 EXPECT_EQ(OK, rv);
7064}
7065
[email protected]23e482282013-06-14 16:08:027066TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277067 HttpRequestInfo request;
7068 request.method = "GET";
7069 request.url = GURL("http://www.google.com/");
7070 request.load_flags = 0;
7071
[email protected]bb88e1d32013-05-03 23:11:077072 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207073 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7074 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077075 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027076
[email protected]3fe8d2f82013-10-17 08:56:077077 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027078 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027080
[email protected]3cd17242009-06-23 02:59:027081 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7082 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7083
7084 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067085 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027086 MockWrite("GET / HTTP/1.1\r\n"
7087 "Host: www.google.com\r\n"
7088 "Connection: keep-alive\r\n\r\n")
7089 };
7090
7091 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067092 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027093 MockRead("HTTP/1.0 200 OK\r\n"),
7094 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7095 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067096 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027097 };
7098
[email protected]31a2bfe2010-02-09 08:03:397099 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7100 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077101 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027102
[email protected]49639fa2011-12-20 23:22:417103 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027104
[email protected]49639fa2011-12-20 23:22:417105 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027106 EXPECT_EQ(ERR_IO_PENDING, rv);
7107
7108 rv = callback.WaitForResult();
7109 EXPECT_EQ(OK, rv);
7110
7111 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507112 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027113
[email protected]029c83b62013-01-24 05:28:207114 LoadTimingInfo load_timing_info;
7115 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7116 TestLoadTimingNotReusedWithPac(load_timing_info,
7117 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7118
[email protected]3cd17242009-06-23 02:59:027119 std::string response_text;
7120 rv = ReadTransaction(trans.get(), &response_text);
7121 EXPECT_EQ(OK, rv);
7122 EXPECT_EQ("Payload", response_text);
7123}
7124
[email protected]23e482282013-06-14 16:08:027125TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277126 HttpRequestInfo request;
7127 request.method = "GET";
7128 request.url = GURL("https://www.google.com/");
7129 request.load_flags = 0;
7130
[email protected]bb88e1d32013-05-03 23:11:077131 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207132 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7133 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077134 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027135
[email protected]3fe8d2f82013-10-17 08:56:077136 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027137 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077138 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027139
[email protected]3cd17242009-06-23 02:59:027140 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7141 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7142
7143 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067144 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357145 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027146 MockWrite("GET / HTTP/1.1\r\n"
7147 "Host: www.google.com\r\n"
7148 "Connection: keep-alive\r\n\r\n")
7149 };
7150
7151 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017152 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7153 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357154 MockRead("HTTP/1.0 200 OK\r\n"),
7155 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7156 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067157 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357158 };
7159
[email protected]31a2bfe2010-02-09 08:03:397160 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7161 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077162 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357163
[email protected]8ddf8322012-02-23 18:08:067164 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357166
[email protected]49639fa2011-12-20 23:22:417167 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357168
[email protected]49639fa2011-12-20 23:22:417169 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357170 EXPECT_EQ(ERR_IO_PENDING, rv);
7171
7172 rv = callback.WaitForResult();
7173 EXPECT_EQ(OK, rv);
7174
[email protected]029c83b62013-01-24 05:28:207175 LoadTimingInfo load_timing_info;
7176 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7177 TestLoadTimingNotReusedWithPac(load_timing_info,
7178 CONNECT_TIMING_HAS_SSL_TIMES);
7179
[email protected]e0c27be2009-07-15 13:09:357180 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507181 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357182
7183 std::string response_text;
7184 rv = ReadTransaction(trans.get(), &response_text);
7185 EXPECT_EQ(OK, rv);
7186 EXPECT_EQ("Payload", response_text);
7187}
7188
[email protected]23e482282013-06-14 16:08:027189TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207190 HttpRequestInfo request;
7191 request.method = "GET";
7192 request.url = GURL("http://www.google.com/");
7193 request.load_flags = 0;
7194
[email protected]bb88e1d32013-05-03 23:11:077195 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207196 ProxyService::CreateFixed("socks4://myproxy:1080"));
7197 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077198 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207199
[email protected]3fe8d2f82013-10-17 08:56:077200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207201 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:207203
7204 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7205 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7206
7207 MockWrite data_writes[] = {
7208 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7209 MockWrite("GET / HTTP/1.1\r\n"
7210 "Host: www.google.com\r\n"
7211 "Connection: keep-alive\r\n\r\n")
7212 };
7213
7214 MockRead data_reads[] = {
7215 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7216 MockRead("HTTP/1.0 200 OK\r\n"),
7217 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7218 MockRead("Payload"),
7219 MockRead(SYNCHRONOUS, OK)
7220 };
7221
7222 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7223 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077224 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207225
7226 TestCompletionCallback callback;
7227
7228 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7229 EXPECT_EQ(ERR_IO_PENDING, rv);
7230
7231 rv = callback.WaitForResult();
7232 EXPECT_EQ(OK, rv);
7233
7234 const HttpResponseInfo* response = trans->GetResponseInfo();
7235 ASSERT_TRUE(response != NULL);
7236
7237 LoadTimingInfo load_timing_info;
7238 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7239 TestLoadTimingNotReused(load_timing_info,
7240 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7241
7242 std::string response_text;
7243 rv = ReadTransaction(trans.get(), &response_text);
7244 EXPECT_EQ(OK, rv);
7245 EXPECT_EQ("Payload", response_text);
7246}
7247
[email protected]23e482282013-06-14 16:08:027248TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277249 HttpRequestInfo request;
7250 request.method = "GET";
7251 request.url = GURL("http://www.google.com/");
7252 request.load_flags = 0;
7253
[email protected]bb88e1d32013-05-03 23:11:077254 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207255 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7256 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077257 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357258
[email protected]3fe8d2f82013-10-17 08:56:077259 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357260 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357262
[email protected]e0c27be2009-07-15 13:09:357263 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7264 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377265 const char kSOCKS5OkRequest[] = {
7266 0x05, // Version
7267 0x01, // Command (CONNECT)
7268 0x00, // Reserved.
7269 0x03, // Address type (DOMAINNAME).
7270 0x0E, // Length of domain (14)
7271 // Domain string:
7272 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7273 0x00, 0x50, // 16-bit port (80)
7274 };
[email protected]e0c27be2009-07-15 13:09:357275 const char kSOCKS5OkResponse[] =
7276 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7277
7278 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067279 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7280 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357281 MockWrite("GET / HTTP/1.1\r\n"
7282 "Host: www.google.com\r\n"
7283 "Connection: keep-alive\r\n\r\n")
7284 };
7285
7286 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017287 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7288 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357289 MockRead("HTTP/1.0 200 OK\r\n"),
7290 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7291 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067292 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357293 };
7294
[email protected]31a2bfe2010-02-09 08:03:397295 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7296 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077297 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357298
[email protected]49639fa2011-12-20 23:22:417299 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357300
[email protected]49639fa2011-12-20 23:22:417301 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357302 EXPECT_EQ(ERR_IO_PENDING, rv);
7303
7304 rv = callback.WaitForResult();
7305 EXPECT_EQ(OK, rv);
7306
7307 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507308 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357309
[email protected]029c83b62013-01-24 05:28:207310 LoadTimingInfo load_timing_info;
7311 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7312 TestLoadTimingNotReusedWithPac(load_timing_info,
7313 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7314
[email protected]e0c27be2009-07-15 13:09:357315 std::string response_text;
7316 rv = ReadTransaction(trans.get(), &response_text);
7317 EXPECT_EQ(OK, rv);
7318 EXPECT_EQ("Payload", response_text);
7319}
7320
[email protected]23e482282013-06-14 16:08:027321TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277322 HttpRequestInfo request;
7323 request.method = "GET";
7324 request.url = GURL("https://www.google.com/");
7325 request.load_flags = 0;
7326
[email protected]bb88e1d32013-05-03 23:11:077327 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207328 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7329 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077330 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357331
[email protected]3fe8d2f82013-10-17 08:56:077332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357333 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357335
[email protected]e0c27be2009-07-15 13:09:357336 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7337 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377338 const unsigned char kSOCKS5OkRequest[] = {
7339 0x05, // Version
7340 0x01, // Command (CONNECT)
7341 0x00, // Reserved.
7342 0x03, // Address type (DOMAINNAME).
7343 0x0E, // Length of domain (14)
7344 // Domain string:
7345 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7346 0x01, 0xBB, // 16-bit port (443)
7347 };
7348
[email protected]e0c27be2009-07-15 13:09:357349 const char kSOCKS5OkResponse[] =
7350 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7351
7352 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067353 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7354 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357355 arraysize(kSOCKS5OkRequest)),
7356 MockWrite("GET / HTTP/1.1\r\n"
7357 "Host: www.google.com\r\n"
7358 "Connection: keep-alive\r\n\r\n")
7359 };
7360
7361 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017362 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7363 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027364 MockRead("HTTP/1.0 200 OK\r\n"),
7365 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7366 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067367 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027368 };
7369
[email protected]31a2bfe2010-02-09 08:03:397370 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7371 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077372 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027373
[email protected]8ddf8322012-02-23 18:08:067374 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027376
[email protected]49639fa2011-12-20 23:22:417377 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027378
[email protected]49639fa2011-12-20 23:22:417379 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027380 EXPECT_EQ(ERR_IO_PENDING, rv);
7381
7382 rv = callback.WaitForResult();
7383 EXPECT_EQ(OK, rv);
7384
7385 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507386 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027387
[email protected]029c83b62013-01-24 05:28:207388 LoadTimingInfo load_timing_info;
7389 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7390 TestLoadTimingNotReusedWithPac(load_timing_info,
7391 CONNECT_TIMING_HAS_SSL_TIMES);
7392
[email protected]3cd17242009-06-23 02:59:027393 std::string response_text;
7394 rv = ReadTransaction(trans.get(), &response_text);
7395 EXPECT_EQ(OK, rv);
7396 EXPECT_EQ("Payload", response_text);
7397}
7398
[email protected]448d4ca52012-03-04 04:12:237399namespace {
7400
[email protected]04e5be32009-06-26 20:00:317401// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067402
7403struct GroupNameTest {
7404 std::string proxy_server;
7405 std::string url;
7406 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187407 bool ssl;
[email protected]2d731a32010-04-29 01:04:067408};
7409
7410scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437411 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077412 SpdySessionDependencies* session_deps_) {
7413 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067414
[email protected]30d4c022013-07-18 22:58:167415 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537416 session->http_server_properties();
7417 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067418 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437419 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067420
7421 return session;
7422}
7423
7424int GroupNameTransactionHelper(
7425 const std::string& url,
7426 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067427 HttpRequestInfo request;
7428 request.method = "GET";
7429 request.url = GURL(url);
7430 request.load_flags = 0;
7431
[email protected]262eec82013-03-19 21:01:367432 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277434
[email protected]49639fa2011-12-20 23:22:417435 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067436
7437 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417438 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067439}
7440
[email protected]448d4ca52012-03-04 04:12:237441} // namespace
7442
[email protected]23e482282013-06-14 16:08:027443TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067444 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317445 {
[email protected]2d731a32010-04-29 01:04:067446 "", // unused
[email protected]04e5be32009-06-26 20:00:317447 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547448 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187449 false,
[email protected]2ff8b312010-04-26 22:20:547450 },
7451 {
[email protected]2d731a32010-04-29 01:04:067452 "", // unused
[email protected]2ff8b312010-04-26 22:20:547453 "http://[2001:1418:13:1::25]/direct",
7454 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187455 false,
[email protected]04e5be32009-06-26 20:00:317456 },
[email protected]04e5be32009-06-26 20:00:317457
7458 // SSL Tests
7459 {
[email protected]2d731a32010-04-29 01:04:067460 "", // unused
[email protected]04e5be32009-06-26 20:00:317461 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027462 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187463 true,
[email protected]04e5be32009-06-26 20:00:317464 },
7465 {
[email protected]2d731a32010-04-29 01:04:067466 "", // unused
7467 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027468 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187469 true,
[email protected]04e5be32009-06-26 20:00:317470 },
7471 {
[email protected]2d731a32010-04-29 01:04:067472 "", // unused
[email protected]2ff8b312010-04-26 22:20:547473 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027474 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187475 true,
[email protected]2ff8b312010-04-26 22:20:547476 },
[email protected]2d731a32010-04-29 01:04:067477 };
[email protected]2ff8b312010-04-26 22:20:547478
[email protected]8e6441ca2010-08-19 05:56:387479 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067480
7481 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077482 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027483 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067484 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437485 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067486
7487 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287488 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7489 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137490 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347491 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447492 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7493 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027494 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7495 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447496 peer.SetClientSocketPoolManager(
7497 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067498
7499 EXPECT_EQ(ERR_IO_PENDING,
7500 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187501 if (tests[i].ssl)
7502 EXPECT_EQ(tests[i].expected_group_name,
7503 ssl_conn_pool->last_group_name_received());
7504 else
7505 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287506 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067507 }
7508
[email protected]2d731a32010-04-29 01:04:067509}
7510
[email protected]23e482282013-06-14 16:08:027511TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067512 const GroupNameTest tests[] = {
7513 {
7514 "http_proxy",
7515 "http://www.google.com/http_proxy_normal",
7516 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187517 false,
[email protected]2d731a32010-04-29 01:04:067518 },
7519
7520 // SSL Tests
7521 {
7522 "http_proxy",
7523 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027524 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187525 true,
[email protected]2d731a32010-04-29 01:04:067526 },
[email protected]af3490e2010-10-16 21:02:297527
[email protected]9faeded92010-04-29 20:03:057528 {
7529 "http_proxy",
7530 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027531 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187532 true,
[email protected]9faeded92010-04-29 20:03:057533 },
[email protected]45499252013-01-23 17:12:567534
7535 {
7536 "http_proxy",
7537 "ftp://ftp.google.com/http_proxy_normal",
7538 "ftp/ftp.google.com:21",
7539 false,
7540 },
[email protected]2d731a32010-04-29 01:04:067541 };
7542
[email protected]8e6441ca2010-08-19 05:56:387543 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067544
7545 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077546 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027547 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067548 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437549 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067550
7551 HttpNetworkSessionPeer peer(session);
7552
[email protected]e60e47a2010-07-14 03:37:187553 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137554 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347555 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137556 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347557 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027558
[email protected]831e4a32013-11-14 02:14:447559 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7560 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027561 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7562 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447563 peer.SetClientSocketPoolManager(
7564 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067565
7566 EXPECT_EQ(ERR_IO_PENDING,
7567 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187568 if (tests[i].ssl)
7569 EXPECT_EQ(tests[i].expected_group_name,
7570 ssl_conn_pool->last_group_name_received());
7571 else
7572 EXPECT_EQ(tests[i].expected_group_name,
7573 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067574 }
[email protected]2d731a32010-04-29 01:04:067575}
7576
[email protected]23e482282013-06-14 16:08:027577TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067578 const GroupNameTest tests[] = {
7579 {
7580 "socks4://socks_proxy:1080",
7581 "http://www.google.com/socks4_direct",
7582 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187583 false,
[email protected]2d731a32010-04-29 01:04:067584 },
7585 {
7586 "socks5://socks_proxy:1080",
7587 "http://www.google.com/socks5_direct",
7588 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187589 false,
[email protected]2d731a32010-04-29 01:04:067590 },
7591
7592 // SSL Tests
7593 {
7594 "socks4://socks_proxy:1080",
7595 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027596 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187597 true,
[email protected]2d731a32010-04-29 01:04:067598 },
7599 {
7600 "socks5://socks_proxy:1080",
7601 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027602 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187603 true,
[email protected]2d731a32010-04-29 01:04:067604 },
[email protected]af3490e2010-10-16 21:02:297605
[email protected]9faeded92010-04-29 20:03:057606 {
7607 "socks4://socks_proxy:1080",
7608 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027609 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187610 true,
[email protected]9faeded92010-04-29 20:03:057611 },
[email protected]04e5be32009-06-26 20:00:317612 };
7613
[email protected]8e6441ca2010-08-19 05:56:387614 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547615
[email protected]04e5be32009-06-26 20:00:317616 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077617 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027618 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067619 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437620 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027621
[email protected]2d731a32010-04-29 01:04:067622 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317623
[email protected]e60e47a2010-07-14 03:37:187624 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137625 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347626 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137627 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347628 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027629
[email protected]831e4a32013-11-14 02:14:447630 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7631 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027632 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7633 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447634 peer.SetClientSocketPoolManager(
7635 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317636
[email protected]262eec82013-03-19 21:01:367637 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317639
[email protected]2d731a32010-04-29 01:04:067640 EXPECT_EQ(ERR_IO_PENDING,
7641 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187642 if (tests[i].ssl)
7643 EXPECT_EQ(tests[i].expected_group_name,
7644 ssl_conn_pool->last_group_name_received());
7645 else
7646 EXPECT_EQ(tests[i].expected_group_name,
7647 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317648 }
7649}
7650
[email protected]23e482282013-06-14 16:08:027651TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277652 HttpRequestInfo request;
7653 request.method = "GET";
7654 request.url = GURL("http://www.google.com/");
7655
[email protected]bb88e1d32013-05-03 23:11:077656 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007657 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327658
[email protected]69719062010-01-05 20:09:217659 // This simulates failure resolving all hostnames; that means we will fail
7660 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077661 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327662
[email protected]3fe8d2f82013-10-17 08:56:077663 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257664 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077665 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257666
[email protected]49639fa2011-12-20 23:22:417667 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257668
[email protected]49639fa2011-12-20 23:22:417669 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257670 EXPECT_EQ(ERR_IO_PENDING, rv);
7671
[email protected]9172a982009-06-06 00:30:257672 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017673 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257674}
7675
[email protected]685af592010-05-11 19:31:247676// Base test to make sure that when the load flags for a request specify to
7677// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027678void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077679 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277680 // Issue a request, asking to bypass the cache(s).
7681 HttpRequestInfo request;
7682 request.method = "GET";
7683 request.load_flags = load_flags;
7684 request.url = GURL("http://www.google.com/");
7685
[email protected]a2c2fb92009-07-18 07:31:047686 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077687 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327688
[email protected]3fe8d2f82013-10-17 08:56:077689 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7690 scoped_ptr<HttpTransaction> trans(
7691 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287692
[email protected]6e78dfb2011-07-28 21:34:477693 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287694 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297695 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077696 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107697 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7698 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417699 &addrlist,
7700 callback.callback(),
7701 NULL,
7702 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477703 EXPECT_EQ(ERR_IO_PENDING, rv);
7704 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287705 EXPECT_EQ(OK, rv);
7706
7707 // Verify that it was added to host cache, by doing a subsequent async lookup
7708 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077709 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107710 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7711 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417712 &addrlist,
7713 callback.callback(),
7714 NULL,
7715 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327716 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287717
7718 // Inject a failure the next time that "www.google.com" is resolved. This way
7719 // we can tell if the next lookup hit the cache, or the "network".
7720 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077721 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287722
7723 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7724 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067725 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397726 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077727 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287728
[email protected]3b9cca42009-06-16 01:08:287729 // Run the request.
[email protected]49639fa2011-12-20 23:22:417730 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287731 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417732 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287733
7734 // If we bypassed the cache, we would have gotten a failure while resolving
7735 // "www.google.com".
7736 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7737}
7738
[email protected]685af592010-05-11 19:31:247739// There are multiple load flags that should trigger the host cache bypass.
7740// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027741TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247742 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7743}
7744
[email protected]23e482282013-06-14 16:08:027745TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247746 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7747}
7748
[email protected]23e482282013-06-14 16:08:027749TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247750 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7751}
7752
[email protected]0877e3d2009-10-17 22:29:577753// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027754TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577755 HttpRequestInfo request;
7756 request.method = "GET";
7757 request.url = GURL("http://www.foo.com/");
7758 request.load_flags = 0;
7759
7760 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067761 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577762 };
[email protected]31a2bfe2010-02-09 08:03:397763 StaticSocketDataProvider data(NULL, 0,
7764 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077765 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077766 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577767
[email protected]49639fa2011-12-20 23:22:417768 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577769
7770 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077771 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577772
[email protected]49639fa2011-12-20 23:22:417773 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577774 EXPECT_EQ(ERR_IO_PENDING, rv);
7775
7776 rv = callback.WaitForResult();
7777 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7778}
7779
7780// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027781TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577782 HttpRequestInfo request;
7783 request.method = "GET";
7784 request.url = GURL("http://www.foo.com/");
7785 request.load_flags = 0;
7786
7787 MockRead data_reads[] = {
7788 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067789 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577790 };
7791
[email protected]31a2bfe2010-02-09 08:03:397792 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077793 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077794 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577795
[email protected]49639fa2011-12-20 23:22:417796 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577797
7798 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577800
[email protected]49639fa2011-12-20 23:22:417801 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577802 EXPECT_EQ(ERR_IO_PENDING, rv);
7803
7804 rv = callback.WaitForResult();
7805 EXPECT_EQ(OK, rv);
7806
7807 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507808 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577809
[email protected]90499482013-06-01 00:39:507810 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577811 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7812
7813 std::string response_data;
7814 rv = ReadTransaction(trans.get(), &response_data);
7815 EXPECT_EQ(OK, rv);
7816 EXPECT_EQ("", response_data);
7817}
7818
7819// Make sure that a dropped connection while draining the body for auth
7820// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027821TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577822 HttpRequestInfo request;
7823 request.method = "GET";
7824 request.url = GURL("http://www.google.com/");
7825 request.load_flags = 0;
7826
7827 MockWrite data_writes1[] = {
7828 MockWrite("GET / HTTP/1.1\r\n"
7829 "Host: www.google.com\r\n"
7830 "Connection: keep-alive\r\n\r\n"),
7831 };
7832
7833 MockRead data_reads1[] = {
7834 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7835 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7836 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7837 MockRead("Content-Length: 14\r\n\r\n"),
7838 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067839 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577840 };
7841
[email protected]31a2bfe2010-02-09 08:03:397842 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7843 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077844 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577845
7846 // After calling trans->RestartWithAuth(), this is the request we should
7847 // be issuing -- the final header line contains the credentials.
7848 MockWrite data_writes2[] = {
7849 MockWrite("GET / HTTP/1.1\r\n"
7850 "Host: www.google.com\r\n"
7851 "Connection: keep-alive\r\n"
7852 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7853 };
7854
7855 // Lastly, the server responds with the actual content.
7856 MockRead data_reads2[] = {
7857 MockRead("HTTP/1.1 200 OK\r\n"),
7858 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7859 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067860 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577861 };
7862
[email protected]31a2bfe2010-02-09 08:03:397863 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7864 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077865 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077866 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577867
[email protected]49639fa2011-12-20 23:22:417868 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577869
[email protected]262eec82013-03-19 21:01:367870 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507872
[email protected]49639fa2011-12-20 23:22:417873 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577874 EXPECT_EQ(ERR_IO_PENDING, rv);
7875
7876 rv = callback1.WaitForResult();
7877 EXPECT_EQ(OK, rv);
7878
7879 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507880 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047881 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577882
[email protected]49639fa2011-12-20 23:22:417883 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577884
[email protected]49639fa2011-12-20 23:22:417885 rv = trans->RestartWithAuth(
7886 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577887 EXPECT_EQ(ERR_IO_PENDING, rv);
7888
7889 rv = callback2.WaitForResult();
7890 EXPECT_EQ(OK, rv);
7891
7892 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507893 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577894 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7895 EXPECT_EQ(100, response->headers->GetContentLength());
7896}
7897
7898// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027899TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077900 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577901
7902 HttpRequestInfo request;
7903 request.method = "GET";
7904 request.url = GURL("https://www.google.com/");
7905 request.load_flags = 0;
7906
7907 MockRead proxy_reads[] = {
7908 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067909 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577910 };
7911
[email protected]31a2bfe2010-02-09 08:03:397912 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067913 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577914
[email protected]bb88e1d32013-05-03 23:11:077915 session_deps_.socket_factory->AddSocketDataProvider(&data);
7916 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[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
[email protected]bb88e1d32013-05-03 23:11:077920 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577921
[email protected]3fe8d2f82013-10-17 08:56:077922 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577923 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077924 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577925
[email protected]49639fa2011-12-20 23:22:417926 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577927 EXPECT_EQ(ERR_IO_PENDING, rv);
7928
7929 rv = callback.WaitForResult();
7930 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7931}
7932
[email protected]23e482282013-06-14 16:08:027933TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467934 HttpRequestInfo request;
7935 request.method = "GET";
7936 request.url = GURL("http://www.google.com/");
7937 request.load_flags = 0;
7938
[email protected]3fe8d2f82013-10-17 08:56:077939 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277940 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077941 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277942
[email protected]e22e1362009-11-23 21:31:127943 MockRead data_reads[] = {
7944 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067945 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127946 };
[email protected]9492e4a2010-02-24 00:58:467947
7948 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077949 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467950
[email protected]49639fa2011-12-20 23:22:417951 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467952
[email protected]49639fa2011-12-20 23:22:417953 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467954 EXPECT_EQ(ERR_IO_PENDING, rv);
7955
7956 EXPECT_EQ(OK, callback.WaitForResult());
7957
7958 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507959 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467960
[email protected]90499482013-06-01 00:39:507961 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467962 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7963
7964 std::string response_data;
7965 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237966 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127967}
7968
[email protected]23e482282013-06-14 16:08:027969TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157970 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:527971 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:337972 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217973 UploadFileElementReader::ScopedOverridingContentLengthForTests
7974 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337975
[email protected]b2d26cfd2012-12-11 10:36:067976 ScopedVector<UploadElementReader> element_readers;
7977 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367978 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7979 temp_file_path,
7980 0,
7981 kuint64max,
7982 base::Time()));
[email protected]96c77a72013-09-24 09:49:207983 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277984
7985 HttpRequestInfo request;
7986 request.method = "POST";
7987 request.url = GURL("http://www.google.com/upload");
7988 request.upload_data_stream = &upload_data_stream;
7989 request.load_flags = 0;
7990
[email protected]3fe8d2f82013-10-17 08:56:077991 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277992 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:337994
7995 MockRead data_reads[] = {
7996 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7997 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067998 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337999 };
[email protected]31a2bfe2010-02-09 08:03:398000 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078001 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338002
[email protected]49639fa2011-12-20 23:22:418003 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338004
[email protected]49639fa2011-12-20 23:22:418005 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338006 EXPECT_EQ(ERR_IO_PENDING, rv);
8007
8008 rv = callback.WaitForResult();
8009 EXPECT_EQ(OK, rv);
8010
8011 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508012 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338013
[email protected]90499482013-06-01 00:39:508014 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338015 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8016
8017 std::string response_data;
8018 rv = ReadTransaction(trans.get(), &response_data);
8019 EXPECT_EQ(OK, rv);
8020 EXPECT_EQ("hello world", response_data);
8021
[email protected]dd3aa792013-07-16 19:10:238022 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338023}
8024
[email protected]23e482282013-06-14 16:08:028025TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158026 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528027 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368028 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308029 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368030 temp_file_content.length()));
8031 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
8032
[email protected]b2d26cfd2012-12-11 10:36:068033 ScopedVector<UploadElementReader> element_readers;
8034 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368035 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8036 temp_file,
8037 0,
8038 kuint64max,
8039 base::Time()));
[email protected]96c77a72013-09-24 09:49:208040 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278041
8042 HttpRequestInfo request;
8043 request.method = "POST";
8044 request.url = GURL("http://www.google.com/upload");
8045 request.upload_data_stream = &upload_data_stream;
8046 request.load_flags = 0;
8047
[email protected]999dd8c2013-11-12 06:45:548048 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078049 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278050 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:368052
[email protected]999dd8c2013-11-12 06:45:548053 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078054 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368055
[email protected]49639fa2011-12-20 23:22:418056 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368057
[email protected]49639fa2011-12-20 23:22:418058 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368059 EXPECT_EQ(ERR_IO_PENDING, rv);
8060
8061 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548062 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368063
8064 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548065 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368066
[email protected]dd3aa792013-07-16 19:10:238067 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368068}
8069
[email protected]02cad5d2013-10-02 08:14:038070TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8071 class FakeUploadElementReader : public UploadElementReader {
8072 public:
8073 FakeUploadElementReader() {}
8074 virtual ~FakeUploadElementReader() {}
8075
8076 const CompletionCallback& callback() const { return callback_; }
8077
8078 // UploadElementReader overrides:
8079 virtual int Init(const CompletionCallback& callback) OVERRIDE {
8080 callback_ = callback;
8081 return ERR_IO_PENDING;
8082 }
8083 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
8084 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
8085 virtual int Read(IOBuffer* buf,
8086 int buf_length,
8087 const CompletionCallback& callback) OVERRIDE {
8088 return ERR_FAILED;
8089 }
8090
8091 private:
8092 CompletionCallback callback_;
8093 };
8094
8095 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8096 ScopedVector<UploadElementReader> element_readers;
8097 element_readers.push_back(fake_reader);
8098 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8099
8100 HttpRequestInfo request;
8101 request.method = "POST";
8102 request.url = GURL("http://www.google.com/upload");
8103 request.upload_data_stream = &upload_data_stream;
8104 request.load_flags = 0;
8105
[email protected]3fe8d2f82013-10-17 08:56:078106 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038107 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078108 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:038109
8110 StaticSocketDataProvider data;
8111 session_deps_.socket_factory->AddSocketDataProvider(&data);
8112
8113 TestCompletionCallback callback;
8114 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8115 EXPECT_EQ(ERR_IO_PENDING, rv);
8116 base::MessageLoop::current()->RunUntilIdle();
8117
8118 // Transaction is pending on request body initialization.
8119 ASSERT_FALSE(fake_reader->callback().is_null());
8120
8121 // Return Init()'s result after the transaction gets destroyed.
8122 trans.reset();
8123 fake_reader->callback().Run(OK); // Should not crash.
8124}
8125
[email protected]aeefc9e82010-02-19 16:18:278126// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028127TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278128
8129 HttpRequestInfo request;
8130 request.method = "GET";
8131 request.url = GURL("http://www.google.com/");
8132 request.load_flags = 0;
8133
8134 // First transaction will request a resource and receive a Basic challenge
8135 // with realm="first_realm".
8136 MockWrite data_writes1[] = {
8137 MockWrite("GET / HTTP/1.1\r\n"
8138 "Host: www.google.com\r\n"
8139 "Connection: keep-alive\r\n"
8140 "\r\n"),
8141 };
8142 MockRead data_reads1[] = {
8143 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8144 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8145 "\r\n"),
8146 };
8147
8148 // After calling trans->RestartWithAuth(), provide an Authentication header
8149 // for first_realm. The server will reject and provide a challenge with
8150 // second_realm.
8151 MockWrite data_writes2[] = {
8152 MockWrite("GET / HTTP/1.1\r\n"
8153 "Host: www.google.com\r\n"
8154 "Connection: keep-alive\r\n"
8155 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8156 "\r\n"),
8157 };
8158 MockRead data_reads2[] = {
8159 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8160 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8161 "\r\n"),
8162 };
8163
8164 // This again fails, and goes back to first_realm. Make sure that the
8165 // entry is removed from cache.
8166 MockWrite data_writes3[] = {
8167 MockWrite("GET / HTTP/1.1\r\n"
8168 "Host: www.google.com\r\n"
8169 "Connection: keep-alive\r\n"
8170 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8171 "\r\n"),
8172 };
8173 MockRead data_reads3[] = {
8174 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8175 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8176 "\r\n"),
8177 };
8178
8179 // Try one last time (with the correct password) and get the resource.
8180 MockWrite data_writes4[] = {
8181 MockWrite("GET / HTTP/1.1\r\n"
8182 "Host: www.google.com\r\n"
8183 "Connection: keep-alive\r\n"
8184 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8185 "\r\n"),
8186 };
8187 MockRead data_reads4[] = {
8188 MockRead("HTTP/1.1 200 OK\r\n"
8189 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508190 "Content-Length: 5\r\n"
8191 "\r\n"
8192 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278193 };
8194
8195 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8196 data_writes1, arraysize(data_writes1));
8197 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8198 data_writes2, arraysize(data_writes2));
8199 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8200 data_writes3, arraysize(data_writes3));
8201 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8202 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078203 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8204 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8205 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8206 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278207
[email protected]49639fa2011-12-20 23:22:418208 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278209
[email protected]3fe8d2f82013-10-17 08:56:078210 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508211 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:508213
[email protected]aeefc9e82010-02-19 16:18:278214 // Issue the first request with Authorize headers. There should be a
8215 // password prompt for first_realm waiting to be filled in after the
8216 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418217 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278218 EXPECT_EQ(ERR_IO_PENDING, rv);
8219 rv = callback1.WaitForResult();
8220 EXPECT_EQ(OK, rv);
8221 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508222 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048223 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8224 ASSERT_FALSE(challenge == NULL);
8225 EXPECT_FALSE(challenge->is_proxy);
8226 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8227 EXPECT_EQ("first_realm", challenge->realm);
8228 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278229
8230 // Issue the second request with an incorrect password. There should be a
8231 // password prompt for second_realm waiting to be filled in after the
8232 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418233 TestCompletionCallback callback2;
8234 rv = trans->RestartWithAuth(
8235 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278236 EXPECT_EQ(ERR_IO_PENDING, rv);
8237 rv = callback2.WaitForResult();
8238 EXPECT_EQ(OK, rv);
8239 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508240 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048241 challenge = response->auth_challenge.get();
8242 ASSERT_FALSE(challenge == NULL);
8243 EXPECT_FALSE(challenge->is_proxy);
8244 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8245 EXPECT_EQ("second_realm", challenge->realm);
8246 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278247
8248 // Issue the third request with another incorrect password. There should be
8249 // a password prompt for first_realm waiting to be filled in. If the password
8250 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8251 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418252 TestCompletionCallback callback3;
8253 rv = trans->RestartWithAuth(
8254 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278255 EXPECT_EQ(ERR_IO_PENDING, rv);
8256 rv = callback3.WaitForResult();
8257 EXPECT_EQ(OK, rv);
8258 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508259 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048260 challenge = response->auth_challenge.get();
8261 ASSERT_FALSE(challenge == NULL);
8262 EXPECT_FALSE(challenge->is_proxy);
8263 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8264 EXPECT_EQ("first_realm", challenge->realm);
8265 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278266
8267 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418268 TestCompletionCallback callback4;
8269 rv = trans->RestartWithAuth(
8270 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278271 EXPECT_EQ(ERR_IO_PENDING, rv);
8272 rv = callback4.WaitForResult();
8273 EXPECT_EQ(OK, rv);
8274 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508275 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278276 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8277}
8278
[email protected]23e482282013-06-14 16:08:028279TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:038280 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:238281 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:428282
[email protected]8a0fc822013-06-27 20:52:438283 std::string alternate_protocol_http_header =
8284 GetAlternateProtocolHttpHeader();
8285
[email protected]564b4912010-03-09 16:30:428286 MockRead data_reads[] = {
8287 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438288 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428289 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068290 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428291 };
8292
8293 HttpRequestInfo request;
8294 request.method = "GET";
8295 request.url = GURL("http://www.google.com/");
8296 request.load_flags = 0;
8297
8298 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8299
[email protected]bb88e1d32013-05-03 23:11:078300 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428301
[email protected]49639fa2011-12-20 23:22:418302 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428303
[email protected]bb88e1d32013-05-03 23:11:078304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368305 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428307
[email protected]49639fa2011-12-20 23:22:418308 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428309 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538310
[email protected]2fbaecf22010-07-22 22:20:358311 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558312 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538313 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428314 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538315 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428316
8317 EXPECT_EQ(OK, callback.WaitForResult());
8318
8319 const HttpResponseInfo* response = trans->GetResponseInfo();
8320 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508321 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428322 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538323 EXPECT_FALSE(response->was_fetched_via_spdy);
8324 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428325
8326 std::string response_data;
8327 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8328 EXPECT_EQ("hello world", response_data);
8329
[email protected]17291a022011-10-10 07:32:538330 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8331 const PortAlternateProtocolPair alternate =
8332 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8333 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428334 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438335 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428336 EXPECT_TRUE(expected_alternate.Equals(alternate));
8337}
8338
[email protected]23e482282013-06-14 16:08:028339TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238340 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388341 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428342
8343 HttpRequestInfo request;
8344 request.method = "GET";
8345 request.url = GURL("http://www.google.com/");
8346 request.load_flags = 0;
8347
[email protected]d973e99a2012-02-17 21:02:368348 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428349 StaticSocketDataProvider first_data;
8350 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078351 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428352
8353 MockRead data_reads[] = {
8354 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8355 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068356 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428357 };
8358 StaticSocketDataProvider second_data(
8359 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078360 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428361
[email protected]bb88e1d32013-05-03 23:11:078362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428363
[email protected]30d4c022013-07-18 22:58:168364 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538365 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118366 // Port must be < 1024, or the header will be ignored (since initial port was
8367 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538368 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118369 HostPortPair::FromURL(request.url),
8370 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438371 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428372
[email protected]262eec82013-03-19 21:01:368373 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508374 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418375 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428376
[email protected]49639fa2011-12-20 23:22:418377 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428378 EXPECT_EQ(ERR_IO_PENDING, rv);
8379 EXPECT_EQ(OK, callback.WaitForResult());
8380
8381 const HttpResponseInfo* response = trans->GetResponseInfo();
8382 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508383 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428384 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8385
8386 std::string response_data;
8387 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8388 EXPECT_EQ("hello world", response_data);
8389
[email protected]17291a022011-10-10 07:32:538390 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118391 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538392 const PortAlternateProtocolPair alternate =
8393 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118394 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538395 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428396}
8397
[email protected]23e482282013-06-14 16:08:028398TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238399 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118400 // Ensure that we're not allowed to redirect traffic via an alternate
8401 // protocol to an unrestricted (port >= 1024) when the original traffic was
8402 // on a restricted port (port < 1024). Ensure that we can redirect in all
8403 // other cases.
8404 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118405
8406 HttpRequestInfo restricted_port_request;
8407 restricted_port_request.method = "GET";
8408 restricted_port_request.url = GURL("http://www.google.com:1023/");
8409 restricted_port_request.load_flags = 0;
8410
[email protected]d973e99a2012-02-17 21:02:368411 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118412 StaticSocketDataProvider first_data;
8413 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078414 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118415
8416 MockRead data_reads[] = {
8417 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8418 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068419 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118420 };
8421 StaticSocketDataProvider second_data(
8422 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078423 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118424
[email protected]bb88e1d32013-05-03 23:11:078425 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118426
[email protected]30d4c022013-07-18 22:58:168427 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538428 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118429 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538430 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118431 HostPortPair::FromURL(restricted_port_request.url),
8432 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438433 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118434
[email protected]262eec82013-03-19 21:01:368435 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418437 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118438
[email protected]49639fa2011-12-20 23:22:418439 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368440 &restricted_port_request,
8441 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118442 EXPECT_EQ(ERR_IO_PENDING, rv);
8443 // Invalid change to unrestricted port should fail.
8444 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198445}
[email protected]3912662a32011-10-04 00:51:118446
[email protected]23e482282013-06-14 16:08:028447TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198448 AlternateProtocolPortRestrictedPermitted) {
8449 // Ensure that we're allowed to redirect traffic via an alternate
8450 // protocol to an unrestricted (port >= 1024) when the original traffic was
8451 // on a restricted port (port < 1024) if we set
8452 // enable_user_alternate_protocol_ports.
8453
8454 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078455 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198456
8457 HttpRequestInfo restricted_port_request;
8458 restricted_port_request.method = "GET";
8459 restricted_port_request.url = GURL("http://www.google.com:1023/");
8460 restricted_port_request.load_flags = 0;
8461
8462 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8463 StaticSocketDataProvider first_data;
8464 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078465 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198466
8467 MockRead data_reads[] = {
8468 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8469 MockRead("hello world"),
8470 MockRead(ASYNC, OK),
8471 };
8472 StaticSocketDataProvider second_data(
8473 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078474 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198475
[email protected]bb88e1d32013-05-03 23:11:078476 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198477
[email protected]30d4c022013-07-18 22:58:168478 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198479 session->http_server_properties();
8480 const int kUnrestrictedAlternatePort = 1024;
8481 http_server_properties->SetAlternateProtocol(
8482 HostPortPair::FromURL(restricted_port_request.url),
8483 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438484 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198485
[email protected]262eec82013-03-19 21:01:368486 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198488 TestCompletionCallback callback;
8489
8490 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368491 &restricted_port_request,
8492 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198493 // Change to unrestricted port should succeed.
8494 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118495}
8496
[email protected]23e482282013-06-14 16:08:028497TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238498 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118499 // Ensure that we're not allowed to redirect traffic via an alternate
8500 // protocol to an unrestricted (port >= 1024) when the original traffic was
8501 // on a restricted port (port < 1024). Ensure that we can redirect in all
8502 // other cases.
8503 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118504
8505 HttpRequestInfo restricted_port_request;
8506 restricted_port_request.method = "GET";
8507 restricted_port_request.url = GURL("http://www.google.com:1023/");
8508 restricted_port_request.load_flags = 0;
8509
[email protected]d973e99a2012-02-17 21:02:368510 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118511 StaticSocketDataProvider first_data;
8512 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078513 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118514
8515 MockRead data_reads[] = {
8516 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8517 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068518 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118519 };
8520 StaticSocketDataProvider second_data(
8521 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078522 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118523
[email protected]bb88e1d32013-05-03 23:11:078524 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118525
[email protected]30d4c022013-07-18 22:58:168526 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538527 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118528 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538529 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118530 HostPortPair::FromURL(restricted_port_request.url),
8531 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438532 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118533
[email protected]262eec82013-03-19 21:01:368534 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508535 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418536 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118537
[email protected]49639fa2011-12-20 23:22:418538 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368539 &restricted_port_request,
8540 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118541 EXPECT_EQ(ERR_IO_PENDING, rv);
8542 // Valid change to restricted port should pass.
8543 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118544}
8545
[email protected]23e482282013-06-14 16:08:028546TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238547 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118548 // Ensure that we're not allowed to redirect traffic via an alternate
8549 // protocol to an unrestricted (port >= 1024) when the original traffic was
8550 // on a restricted port (port < 1024). Ensure that we can redirect in all
8551 // other cases.
8552 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118553
8554 HttpRequestInfo unrestricted_port_request;
8555 unrestricted_port_request.method = "GET";
8556 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8557 unrestricted_port_request.load_flags = 0;
8558
[email protected]d973e99a2012-02-17 21:02:368559 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118560 StaticSocketDataProvider first_data;
8561 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078562 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118563
8564 MockRead data_reads[] = {
8565 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8566 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068567 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118568 };
8569 StaticSocketDataProvider second_data(
8570 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078571 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118572
[email protected]bb88e1d32013-05-03 23:11:078573 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118574
[email protected]30d4c022013-07-18 22:58:168575 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538576 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118577 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538578 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118579 HostPortPair::FromURL(unrestricted_port_request.url),
8580 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438581 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118582
[email protected]262eec82013-03-19 21:01:368583 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508584 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418585 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118586
[email protected]49639fa2011-12-20 23:22:418587 int rv = trans->Start(
8588 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118589 EXPECT_EQ(ERR_IO_PENDING, rv);
8590 // Valid change to restricted port should pass.
8591 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118592}
8593
[email protected]23e482282013-06-14 16:08:028594TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238595 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118596 // Ensure that we're not allowed to redirect traffic via an alternate
8597 // protocol to an unrestricted (port >= 1024) when the original traffic was
8598 // on a restricted port (port < 1024). Ensure that we can redirect in all
8599 // other cases.
8600 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118601
8602 HttpRequestInfo unrestricted_port_request;
8603 unrestricted_port_request.method = "GET";
8604 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8605 unrestricted_port_request.load_flags = 0;
8606
[email protected]d973e99a2012-02-17 21:02:368607 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118608 StaticSocketDataProvider first_data;
8609 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078610 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118611
8612 MockRead data_reads[] = {
8613 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8614 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068615 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118616 };
8617 StaticSocketDataProvider second_data(
8618 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078619 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118620
[email protected]bb88e1d32013-05-03 23:11:078621 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118622
[email protected]30d4c022013-07-18 22:58:168623 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538624 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118625 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538626 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118627 HostPortPair::FromURL(unrestricted_port_request.url),
8628 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438629 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118630
[email protected]262eec82013-03-19 21:01:368631 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508632 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418633 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118634
[email protected]49639fa2011-12-20 23:22:418635 int rv = trans->Start(
8636 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118637 EXPECT_EQ(ERR_IO_PENDING, rv);
8638 // Valid change to an unrestricted port should pass.
8639 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118640}
8641
[email protected]23e482282013-06-14 16:08:028642TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238643 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028644 // Ensure that we're not allowed to redirect traffic via an alternate
8645 // protocol to an unsafe port, and that we resume the second
8646 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8647 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028648
8649 HttpRequestInfo request;
8650 request.method = "GET";
8651 request.url = GURL("http://www.google.com/");
8652 request.load_flags = 0;
8653
8654 // The alternate protocol request will error out before we attempt to connect,
8655 // so only the standard HTTP request will try to connect.
8656 MockRead data_reads[] = {
8657 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8658 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068659 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028660 };
8661 StaticSocketDataProvider data(
8662 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078663 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028664
[email protected]bb88e1d32013-05-03 23:11:078665 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028666
[email protected]30d4c022013-07-18 22:58:168667 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028668 session->http_server_properties();
8669 const int kUnsafePort = 7;
8670 http_server_properties->SetAlternateProtocol(
8671 HostPortPair::FromURL(request.url),
8672 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438673 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028674
[email protected]262eec82013-03-19 21:01:368675 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508676 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028677 TestCompletionCallback callback;
8678
8679 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8680 EXPECT_EQ(ERR_IO_PENDING, rv);
8681 // The HTTP request should succeed.
8682 EXPECT_EQ(OK, callback.WaitForResult());
8683
8684 // Disable alternate protocol before the asserts.
8685 HttpStreamFactory::set_use_alternate_protocols(false);
8686
8687 const HttpResponseInfo* response = trans->GetResponseInfo();
8688 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508689 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028690 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8691
8692 std::string response_data;
8693 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8694 EXPECT_EQ("hello world", response_data);
8695}
8696
[email protected]23e482282013-06-14 16:08:028697TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388698 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038699 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548700
8701 HttpRequestInfo request;
8702 request.method = "GET";
8703 request.url = GURL("http://www.google.com/");
8704 request.load_flags = 0;
8705
[email protected]8a0fc822013-06-27 20:52:438706 std::string alternate_protocol_http_header =
8707 GetAlternateProtocolHttpHeader();
8708
[email protected]2ff8b312010-04-26 22:20:548709 MockRead data_reads[] = {
8710 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438711 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548712 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178713 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8714 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548715 };
8716
8717 StaticSocketDataProvider first_transaction(
8718 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078719 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548720
[email protected]8ddf8322012-02-23 18:08:068721 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028722 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548724
[email protected]cdf8f7e72013-05-23 10:56:468725 scoped_ptr<SpdyFrame> req(
8726 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138727 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548728
[email protected]23e482282013-06-14 16:08:028729 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8730 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548731 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138732 CreateMockRead(*resp),
8733 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068734 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548735 };
8736
[email protected]dd54bd82012-07-19 23:44:578737 DelayedSocketData spdy_data(
8738 1, // wait for one write to finish before reading.
8739 spdy_reads, arraysize(spdy_reads),
8740 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078741 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548742
[email protected]d973e99a2012-02-17 21:02:368743 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558744 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8745 NULL, 0, NULL, 0);
8746 hanging_non_alternate_protocol_socket.set_connect_data(
8747 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078748 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558749 &hanging_non_alternate_protocol_socket);
8750
[email protected]49639fa2011-12-20 23:22:418751 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548752
[email protected]bb88e1d32013-05-03 23:11:078753 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368754 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548756
[email protected]49639fa2011-12-20 23:22:418757 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548758 EXPECT_EQ(ERR_IO_PENDING, rv);
8759 EXPECT_EQ(OK, callback.WaitForResult());
8760
8761 const HttpResponseInfo* response = trans->GetResponseInfo();
8762 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508763 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548764 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8765
8766 std::string response_data;
8767 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8768 EXPECT_EQ("hello world", response_data);
8769
[email protected]90499482013-06-01 00:39:508770 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548771
[email protected]49639fa2011-12-20 23:22:418772 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548773 EXPECT_EQ(ERR_IO_PENDING, rv);
8774 EXPECT_EQ(OK, callback.WaitForResult());
8775
8776 response = trans->GetResponseInfo();
8777 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508778 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548779 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538780 EXPECT_TRUE(response->was_fetched_via_spdy);
8781 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548782
8783 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8784 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548785}
8786
[email protected]23e482282013-06-14 16:08:028787TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558788 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038789 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558790
8791 HttpRequestInfo request;
8792 request.method = "GET";
8793 request.url = GURL("http://www.google.com/");
8794 request.load_flags = 0;
8795
[email protected]8a0fc822013-06-27 20:52:438796 std::string alternate_protocol_http_header =
8797 GetAlternateProtocolHttpHeader();
8798
[email protected]2d6728692011-03-12 01:39:558799 MockRead data_reads[] = {
8800 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438801 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558802 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178803 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068804 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558805 };
8806
8807 StaticSocketDataProvider first_transaction(
8808 data_reads, arraysize(data_reads), NULL, 0);
8809 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078810 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558811
[email protected]d973e99a2012-02-17 21:02:368812 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558813 StaticSocketDataProvider hanging_socket(
8814 NULL, 0, NULL, 0);
8815 hanging_socket.set_connect_data(never_finishing_connect);
8816 // Socket 2 and 3 are the hanging Alternate-Protocol and
8817 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078818 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8819 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558820
[email protected]8ddf8322012-02-23 18:08:068821 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028822 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078823 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558824
[email protected]cdf8f7e72013-05-23 10:56:468825 scoped_ptr<SpdyFrame> req1(
8826 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8827 scoped_ptr<SpdyFrame> req2(
8828 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558829 MockWrite spdy_writes[] = {
8830 CreateMockWrite(*req1),
8831 CreateMockWrite(*req2),
8832 };
[email protected]23e482282013-06-14 16:08:028833 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8834 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8835 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8836 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558837 MockRead spdy_reads[] = {
8838 CreateMockRead(*resp1),
8839 CreateMockRead(*data1),
8840 CreateMockRead(*resp2),
8841 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068842 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558843 };
8844
[email protected]dd54bd82012-07-19 23:44:578845 DelayedSocketData spdy_data(
8846 2, // wait for writes to finish before reading.
8847 spdy_reads, arraysize(spdy_reads),
8848 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558849 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078850 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558851
8852 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078853 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558854
[email protected]bb88e1d32013-05-03 23:11:078855 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418856 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508857 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558858
[email protected]49639fa2011-12-20 23:22:418859 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558860 EXPECT_EQ(ERR_IO_PENDING, rv);
8861 EXPECT_EQ(OK, callback1.WaitForResult());
8862
8863 const HttpResponseInfo* response = trans1.GetResponseInfo();
8864 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508865 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558866 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8867
8868 std::string response_data;
8869 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8870 EXPECT_EQ("hello world", response_data);
8871
[email protected]49639fa2011-12-20 23:22:418872 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508873 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418874 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558875 EXPECT_EQ(ERR_IO_PENDING, rv);
8876
[email protected]49639fa2011-12-20 23:22:418877 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508878 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418879 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558880 EXPECT_EQ(ERR_IO_PENDING, rv);
8881
8882 EXPECT_EQ(OK, callback2.WaitForResult());
8883 EXPECT_EQ(OK, callback3.WaitForResult());
8884
8885 response = trans2.GetResponseInfo();
8886 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508887 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558888 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8889 EXPECT_TRUE(response->was_fetched_via_spdy);
8890 EXPECT_TRUE(response->was_npn_negotiated);
8891 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8892 EXPECT_EQ("hello!", response_data);
8893
8894 response = trans3.GetResponseInfo();
8895 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508896 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558897 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8898 EXPECT_TRUE(response->was_fetched_via_spdy);
8899 EXPECT_TRUE(response->was_npn_negotiated);
8900 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8901 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558902}
8903
[email protected]23e482282013-06-14 16:08:028904TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558905 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038906 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558907
8908 HttpRequestInfo request;
8909 request.method = "GET";
8910 request.url = GURL("http://www.google.com/");
8911 request.load_flags = 0;
8912
[email protected]8a0fc822013-06-27 20:52:438913 std::string alternate_protocol_http_header =
8914 GetAlternateProtocolHttpHeader();
8915
[email protected]2d6728692011-03-12 01:39:558916 MockRead data_reads[] = {
8917 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438918 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558919 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178920 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068921 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558922 };
8923
8924 StaticSocketDataProvider first_transaction(
8925 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078926 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558927
[email protected]8ddf8322012-02-23 18:08:068928 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028929 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[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_alternate_protocol_socket(
8934 NULL, 0, NULL, 0);
8935 hanging_alternate_protocol_socket.set_connect_data(
8936 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078937 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558938 &hanging_alternate_protocol_socket);
8939
8940 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078941 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558942
[email protected]49639fa2011-12-20 23:22:418943 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558944
[email protected]bb88e1d32013-05-03 23:11:078945 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368946 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508947 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558948
[email protected]49639fa2011-12-20 23:22:418949 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558950 EXPECT_EQ(ERR_IO_PENDING, rv);
8951 EXPECT_EQ(OK, callback.WaitForResult());
8952
8953 const HttpResponseInfo* response = trans->GetResponseInfo();
8954 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508955 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558956 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8957
8958 std::string response_data;
8959 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8960 EXPECT_EQ("hello world", response_data);
8961
[email protected]90499482013-06-01 00:39:508962 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558963
[email protected]49639fa2011-12-20 23:22:418964 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558965 EXPECT_EQ(ERR_IO_PENDING, rv);
8966 EXPECT_EQ(OK, callback.WaitForResult());
8967
8968 response = trans->GetResponseInfo();
8969 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508970 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558971 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8972 EXPECT_FALSE(response->was_fetched_via_spdy);
8973 EXPECT_FALSE(response->was_npn_negotiated);
8974
8975 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8976 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558977}
8978
[email protected]631f1322010-04-30 17:59:118979class CapturingProxyResolver : public ProxyResolver {
8980 public:
8981 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8982 virtual ~CapturingProxyResolver() {}
8983
8984 virtual int GetProxyForURL(const GURL& url,
8985 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318986 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118987 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168988 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408989 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8990 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428991 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118992 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428993 return OK;
[email protected]631f1322010-04-30 17:59:118994 }
8995
[email protected]46fadfd2013-02-06 09:40:168996 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118997 NOTREACHED();
8998 }
8999
[email protected]f2c971f2011-11-08 00:33:179000 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
9001 NOTREACHED();
9002 return LOAD_STATE_IDLE;
9003 }
9004
[email protected]46fadfd2013-02-06 09:40:169005 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:409006 NOTREACHED();
9007 }
9008
[email protected]24476402010-07-20 20:55:179009 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:169010 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:429011 return OK;
[email protected]631f1322010-04-30 17:59:119012 }
9013
[email protected]24476402010-07-20 20:55:179014 const std::vector<GURL>& resolved() const { return resolved_; }
9015
9016 private:
[email protected]631f1322010-04-30 17:59:119017 std::vector<GURL> resolved_;
9018
9019 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9020};
9021
[email protected]23e482282013-06-14 16:08:029022TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239023 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:389024 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039025 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:119026
9027 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429028 proxy_config.set_auto_detect(true);
9029 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119030
[email protected]631f1322010-04-30 17:59:119031 CapturingProxyResolver* capturing_proxy_resolver =
9032 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079033 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389034 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9035 NULL));
[email protected]029c83b62013-01-24 05:28:209036 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079037 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119038
9039 HttpRequestInfo request;
9040 request.method = "GET";
9041 request.url = GURL("http://www.google.com/");
9042 request.load_flags = 0;
9043
[email protected]8a0fc822013-06-27 20:52:439044 std::string alternate_protocol_http_header =
9045 GetAlternateProtocolHttpHeader();
9046
[email protected]631f1322010-04-30 17:59:119047 MockRead data_reads[] = {
9048 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439049 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119050 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179051 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069052 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119053 };
9054
9055 StaticSocketDataProvider first_transaction(
9056 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079057 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119058
[email protected]8ddf8322012-02-23 18:08:069059 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029060 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119062
[email protected]cdf8f7e72013-05-23 10:56:469063 scoped_ptr<SpdyFrame> req(
9064 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119065 MockWrite spdy_writes[] = {
9066 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9067 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429068 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469069 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119070 };
9071
[email protected]d911f1b2010-05-05 22:39:429072 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9073
[email protected]23e482282013-06-14 16:08:029074 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9075 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119076 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069077 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139078 CreateMockRead(*resp.get(), 4), // 2, 4
9079 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069080 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119081 };
9082
[email protected]dd54bd82012-07-19 23:44:579083 OrderedSocketData spdy_data(
9084 spdy_reads, arraysize(spdy_reads),
9085 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079086 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119087
[email protected]d973e99a2012-02-17 21:02:369088 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559089 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9090 NULL, 0, NULL, 0);
9091 hanging_non_alternate_protocol_socket.set_connect_data(
9092 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079093 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559094 &hanging_non_alternate_protocol_socket);
9095
[email protected]49639fa2011-12-20 23:22:419096 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119097
[email protected]bb88e1d32013-05-03 23:11:079098 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369099 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509100 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119101
[email protected]49639fa2011-12-20 23:22:419102 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119103 EXPECT_EQ(ERR_IO_PENDING, rv);
9104 EXPECT_EQ(OK, callback.WaitForResult());
9105
9106 const HttpResponseInfo* response = trans->GetResponseInfo();
9107 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509108 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119109 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539110 EXPECT_FALSE(response->was_fetched_via_spdy);
9111 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119112
9113 std::string response_data;
9114 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9115 EXPECT_EQ("hello world", response_data);
9116
[email protected]90499482013-06-01 00:39:509117 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119118
[email protected]49639fa2011-12-20 23:22:419119 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119120 EXPECT_EQ(ERR_IO_PENDING, rv);
9121 EXPECT_EQ(OK, callback.WaitForResult());
9122
9123 response = trans->GetResponseInfo();
9124 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509125 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119126 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539127 EXPECT_TRUE(response->was_fetched_via_spdy);
9128 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119129
9130 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9131 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559132 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429133 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119134 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429135 EXPECT_EQ("https://www.google.com/",
9136 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119137
[email protected]029c83b62013-01-24 05:28:209138 LoadTimingInfo load_timing_info;
9139 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9140 TestLoadTimingNotReusedWithPac(load_timing_info,
9141 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119142}
[email protected]631f1322010-04-30 17:59:119143
[email protected]23e482282013-06-14 16:08:029144TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549145 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:389146 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039147 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:549148
9149 HttpRequestInfo request;
9150 request.method = "GET";
9151 request.url = GURL("http://www.google.com/");
9152 request.load_flags = 0;
9153
[email protected]8a0fc822013-06-27 20:52:439154 std::string alternate_protocol_http_header =
9155 GetAlternateProtocolHttpHeader();
9156
[email protected]2ff8b312010-04-26 22:20:549157 MockRead data_reads[] = {
9158 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439159 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549160 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069161 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549162 };
9163
9164 StaticSocketDataProvider first_transaction(
9165 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079166 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549167
[email protected]8ddf8322012-02-23 18:08:069168 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029169 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549171
[email protected]cdf8f7e72013-05-23 10:56:469172 scoped_ptr<SpdyFrame> req(
9173 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139174 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549175
[email protected]23e482282013-06-14 16:08:029176 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9177 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549178 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139179 CreateMockRead(*resp),
9180 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069181 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549182 };
9183
[email protected]dd54bd82012-07-19 23:44:579184 DelayedSocketData spdy_data(
9185 1, // wait for one write to finish before reading.
9186 spdy_reads, arraysize(spdy_reads),
9187 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079188 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549189
[email protected]83039bb2011-12-09 18:43:559190 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549191
[email protected]bb88e1d32013-05-03 23:11:079192 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549193
[email protected]262eec82013-03-19 21:01:369194 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549196
[email protected]49639fa2011-12-20 23:22:419197 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549198 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419199 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549200
9201 const HttpResponseInfo* response = trans->GetResponseInfo();
9202 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509203 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549204 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9205
9206 std::string response_data;
9207 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9208 EXPECT_EQ("hello world", response_data);
9209
9210 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389211 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409212 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539213 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279214 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269215 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389216
[email protected]90499482013-06-01 00:39:509217 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549218
[email protected]49639fa2011-12-20 23:22:419219 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549220 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419221 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549222
9223 response = trans->GetResponseInfo();
9224 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509225 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549226 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539227 EXPECT_TRUE(response->was_fetched_via_spdy);
9228 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549229
9230 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9231 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429232}
9233
[email protected]044de0642010-06-17 10:42:159234// GenerateAuthToken is a mighty big test.
9235// It tests all permutation of GenerateAuthToken behavior:
9236// - Synchronous and Asynchronous completion.
9237// - OK or error on completion.
9238// - Direct connection, non-authenticating proxy, and authenticating proxy.
9239// - HTTP or HTTPS backend (to include proxy tunneling).
9240// - Non-authenticating and authenticating backend.
9241//
[email protected]fe3b7dc2012-02-03 19:52:099242// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159243// problems generating an auth token for an authenticating proxy, we don't
9244// need to test all permutations of the backend server).
9245//
9246// The test proceeds by going over each of the configuration cases, and
9247// potentially running up to three rounds in each of the tests. The TestConfig
9248// specifies both the configuration for the test as well as the expectations
9249// for the results.
[email protected]23e482282013-06-14 16:08:029250TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509251 static const char kServer[] = "http://www.example.com";
9252 static const char kSecureServer[] = "https://www.example.com";
9253 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159254 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9255
9256 enum AuthTiming {
9257 AUTH_NONE,
9258 AUTH_SYNC,
9259 AUTH_ASYNC,
9260 };
9261
9262 const MockWrite kGet(
9263 "GET / HTTP/1.1\r\n"
9264 "Host: www.example.com\r\n"
9265 "Connection: keep-alive\r\n\r\n");
9266 const MockWrite kGetProxy(
9267 "GET http://www.example.com/ HTTP/1.1\r\n"
9268 "Host: www.example.com\r\n"
9269 "Proxy-Connection: keep-alive\r\n\r\n");
9270 const MockWrite kGetAuth(
9271 "GET / HTTP/1.1\r\n"
9272 "Host: www.example.com\r\n"
9273 "Connection: keep-alive\r\n"
9274 "Authorization: auth_token\r\n\r\n");
9275 const MockWrite kGetProxyAuth(
9276 "GET http://www.example.com/ HTTP/1.1\r\n"
9277 "Host: www.example.com\r\n"
9278 "Proxy-Connection: keep-alive\r\n"
9279 "Proxy-Authorization: auth_token\r\n\r\n");
9280 const MockWrite kGetAuthThroughProxy(
9281 "GET http://www.example.com/ HTTP/1.1\r\n"
9282 "Host: www.example.com\r\n"
9283 "Proxy-Connection: keep-alive\r\n"
9284 "Authorization: auth_token\r\n\r\n");
9285 const MockWrite kGetAuthWithProxyAuth(
9286 "GET http://www.example.com/ HTTP/1.1\r\n"
9287 "Host: www.example.com\r\n"
9288 "Proxy-Connection: keep-alive\r\n"
9289 "Proxy-Authorization: auth_token\r\n"
9290 "Authorization: auth_token\r\n\r\n");
9291 const MockWrite kConnect(
9292 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9293 "Host: www.example.com\r\n"
9294 "Proxy-Connection: keep-alive\r\n\r\n");
9295 const MockWrite kConnectProxyAuth(
9296 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9297 "Host: www.example.com\r\n"
9298 "Proxy-Connection: keep-alive\r\n"
9299 "Proxy-Authorization: auth_token\r\n\r\n");
9300
9301 const MockRead kSuccess(
9302 "HTTP/1.1 200 OK\r\n"
9303 "Content-Type: text/html; charset=iso-8859-1\r\n"
9304 "Content-Length: 3\r\n\r\n"
9305 "Yes");
9306 const MockRead kFailure(
9307 "Should not be called.");
9308 const MockRead kServerChallenge(
9309 "HTTP/1.1 401 Unauthorized\r\n"
9310 "WWW-Authenticate: Mock realm=server\r\n"
9311 "Content-Type: text/html; charset=iso-8859-1\r\n"
9312 "Content-Length: 14\r\n\r\n"
9313 "Unauthorized\r\n");
9314 const MockRead kProxyChallenge(
9315 "HTTP/1.1 407 Unauthorized\r\n"
9316 "Proxy-Authenticate: Mock realm=proxy\r\n"
9317 "Proxy-Connection: close\r\n"
9318 "Content-Type: text/html; charset=iso-8859-1\r\n"
9319 "Content-Length: 14\r\n\r\n"
9320 "Unauthorized\r\n");
9321 const MockRead kProxyConnected(
9322 "HTTP/1.1 200 Connection Established\r\n\r\n");
9323
9324 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9325 // no constructors, but the C++ compiler on Windows warns about
9326 // unspecified data in compound literals. So, moved to using constructors,
9327 // and TestRound's created with the default constructor should not be used.
9328 struct TestRound {
9329 TestRound()
9330 : expected_rv(ERR_UNEXPECTED),
9331 extra_write(NULL),
9332 extra_read(NULL) {
9333 }
9334 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9335 int expected_rv_arg)
9336 : write(write_arg),
9337 read(read_arg),
9338 expected_rv(expected_rv_arg),
9339 extra_write(NULL),
9340 extra_read(NULL) {
9341 }
9342 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9343 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019344 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159345 : write(write_arg),
9346 read(read_arg),
9347 expected_rv(expected_rv_arg),
9348 extra_write(extra_write_arg),
9349 extra_read(extra_read_arg) {
9350 }
9351 MockWrite write;
9352 MockRead read;
9353 int expected_rv;
9354 const MockWrite* extra_write;
9355 const MockRead* extra_read;
9356 };
9357
9358 static const int kNoSSL = 500;
9359
9360 struct TestConfig {
9361 const char* proxy_url;
9362 AuthTiming proxy_auth_timing;
9363 int proxy_auth_rv;
9364 const char* server_url;
9365 AuthTiming server_auth_timing;
9366 int server_auth_rv;
9367 int num_auth_rounds;
9368 int first_ssl_round;
9369 TestRound rounds[3];
9370 } test_configs[] = {
9371 // Non-authenticating HTTP server with a direct connection.
9372 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9373 { TestRound(kGet, kSuccess, OK)}},
9374 // Authenticating HTTP server with a direct connection.
9375 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9376 { TestRound(kGet, kServerChallenge, OK),
9377 TestRound(kGetAuth, kSuccess, OK)}},
9378 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9379 { TestRound(kGet, kServerChallenge, OK),
9380 TestRound(kGetAuth, kFailure, kAuthErr)}},
9381 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9382 { TestRound(kGet, kServerChallenge, OK),
9383 TestRound(kGetAuth, kSuccess, OK)}},
9384 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9385 { TestRound(kGet, kServerChallenge, OK),
9386 TestRound(kGetAuth, kFailure, kAuthErr)}},
9387 // Non-authenticating HTTP server through a non-authenticating proxy.
9388 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9389 { TestRound(kGetProxy, kSuccess, OK)}},
9390 // Authenticating HTTP server through a non-authenticating proxy.
9391 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9392 { TestRound(kGetProxy, kServerChallenge, OK),
9393 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9394 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9395 { TestRound(kGetProxy, kServerChallenge, OK),
9396 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9397 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9398 { TestRound(kGetProxy, kServerChallenge, OK),
9399 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9400 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9401 { TestRound(kGetProxy, kServerChallenge, OK),
9402 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9403 // Non-authenticating HTTP server through an authenticating proxy.
9404 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9405 { TestRound(kGetProxy, kProxyChallenge, OK),
9406 TestRound(kGetProxyAuth, kSuccess, OK)}},
9407 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9408 { TestRound(kGetProxy, kProxyChallenge, OK),
9409 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9410 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9411 { TestRound(kGetProxy, kProxyChallenge, OK),
9412 TestRound(kGetProxyAuth, kSuccess, OK)}},
9413 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9414 { TestRound(kGetProxy, kProxyChallenge, OK),
9415 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9416 // Authenticating HTTP server through an authenticating proxy.
9417 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9418 { TestRound(kGetProxy, kProxyChallenge, OK),
9419 TestRound(kGetProxyAuth, kServerChallenge, OK),
9420 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9421 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9422 { TestRound(kGetProxy, kProxyChallenge, OK),
9423 TestRound(kGetProxyAuth, kServerChallenge, OK),
9424 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9425 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9426 { TestRound(kGetProxy, kProxyChallenge, OK),
9427 TestRound(kGetProxyAuth, kServerChallenge, OK),
9428 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9429 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9430 { TestRound(kGetProxy, kProxyChallenge, OK),
9431 TestRound(kGetProxyAuth, kServerChallenge, OK),
9432 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9433 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9434 { TestRound(kGetProxy, kProxyChallenge, OK),
9435 TestRound(kGetProxyAuth, kServerChallenge, OK),
9436 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9437 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9438 { TestRound(kGetProxy, kProxyChallenge, OK),
9439 TestRound(kGetProxyAuth, kServerChallenge, OK),
9440 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9441 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9442 { TestRound(kGetProxy, kProxyChallenge, OK),
9443 TestRound(kGetProxyAuth, kServerChallenge, OK),
9444 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9445 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9446 { TestRound(kGetProxy, kProxyChallenge, OK),
9447 TestRound(kGetProxyAuth, kServerChallenge, OK),
9448 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9449 // Non-authenticating HTTPS server with a direct connection.
9450 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9451 { TestRound(kGet, kSuccess, OK)}},
9452 // Authenticating HTTPS server with a direct connection.
9453 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9454 { TestRound(kGet, kServerChallenge, OK),
9455 TestRound(kGetAuth, kSuccess, OK)}},
9456 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9457 { TestRound(kGet, kServerChallenge, OK),
9458 TestRound(kGetAuth, kFailure, kAuthErr)}},
9459 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9460 { TestRound(kGet, kServerChallenge, OK),
9461 TestRound(kGetAuth, kSuccess, OK)}},
9462 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9463 { TestRound(kGet, kServerChallenge, OK),
9464 TestRound(kGetAuth, kFailure, kAuthErr)}},
9465 // Non-authenticating HTTPS server with a non-authenticating proxy.
9466 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9467 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9468 // Authenticating HTTPS server through a non-authenticating proxy.
9469 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9470 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9471 TestRound(kGetAuth, kSuccess, OK)}},
9472 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9473 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9474 TestRound(kGetAuth, kFailure, kAuthErr)}},
9475 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9476 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9477 TestRound(kGetAuth, kSuccess, OK)}},
9478 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9479 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9480 TestRound(kGetAuth, kFailure, kAuthErr)}},
9481 // Non-Authenticating HTTPS server through an authenticating proxy.
9482 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9483 { TestRound(kConnect, kProxyChallenge, OK),
9484 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9485 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9486 { TestRound(kConnect, kProxyChallenge, OK),
9487 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9488 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9489 { TestRound(kConnect, kProxyChallenge, OK),
9490 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9491 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9492 { TestRound(kConnect, kProxyChallenge, OK),
9493 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9494 // Authenticating HTTPS server through an authenticating proxy.
9495 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9496 { TestRound(kConnect, kProxyChallenge, OK),
9497 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9498 &kGet, &kServerChallenge),
9499 TestRound(kGetAuth, kSuccess, OK)}},
9500 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9501 { TestRound(kConnect, kProxyChallenge, OK),
9502 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9503 &kGet, &kServerChallenge),
9504 TestRound(kGetAuth, kFailure, kAuthErr)}},
9505 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9506 { TestRound(kConnect, kProxyChallenge, OK),
9507 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9508 &kGet, &kServerChallenge),
9509 TestRound(kGetAuth, kSuccess, OK)}},
9510 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9511 { TestRound(kConnect, kProxyChallenge, OK),
9512 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9513 &kGet, &kServerChallenge),
9514 TestRound(kGetAuth, kFailure, kAuthErr)}},
9515 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9516 { TestRound(kConnect, kProxyChallenge, OK),
9517 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9518 &kGet, &kServerChallenge),
9519 TestRound(kGetAuth, kSuccess, OK)}},
9520 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9521 { TestRound(kConnect, kProxyChallenge, OK),
9522 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9523 &kGet, &kServerChallenge),
9524 TestRound(kGetAuth, kFailure, kAuthErr)}},
9525 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9526 { TestRound(kConnect, kProxyChallenge, OK),
9527 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9528 &kGet, &kServerChallenge),
9529 TestRound(kGetAuth, kSuccess, OK)}},
9530 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9531 { TestRound(kConnect, kProxyChallenge, OK),
9532 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9533 &kGet, &kServerChallenge),
9534 TestRound(kGetAuth, kFailure, kAuthErr)}},
9535 };
9536
[email protected]044de0642010-06-17 10:42:159537 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089538 HttpAuthHandlerMock::Factory* auth_factory(
9539 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079540 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159541 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269542
9543 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159544 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089545 for (int n = 0; n < 2; n++) {
9546 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9547 std::string auth_challenge = "Mock realm=proxy";
9548 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249549 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9550 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089551 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9552 origin, BoundNetLog());
9553 auth_handler->SetGenerateExpectation(
9554 test_config.proxy_auth_timing == AUTH_ASYNC,
9555 test_config.proxy_auth_rv);
9556 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9557 }
[email protected]044de0642010-06-17 10:42:159558 }
9559 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009560 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159561 std::string auth_challenge = "Mock realm=server";
9562 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249563 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9564 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159565 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9566 origin, BoundNetLog());
9567 auth_handler->SetGenerateExpectation(
9568 test_config.server_auth_timing == AUTH_ASYNC,
9569 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089570 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159571 }
9572 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079573 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129574 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159575 } else {
[email protected]bb88e1d32013-05-03 23:11:079576 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159577 }
9578
9579 HttpRequestInfo request;
9580 request.method = "GET";
9581 request.url = GURL(test_config.server_url);
9582 request.load_flags = 0;
9583
[email protected]bb88e1d32013-05-03 23:11:079584 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159586
9587 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9588 const TestRound& read_write_round = test_config.rounds[round];
9589
9590 // Set up expected reads and writes.
9591 MockRead reads[2];
9592 reads[0] = read_write_round.read;
9593 size_t length_reads = 1;
9594 if (read_write_round.extra_read) {
9595 reads[1] = *read_write_round.extra_read;
9596 length_reads = 2;
9597 }
9598
9599 MockWrite writes[2];
9600 writes[0] = read_write_round.write;
9601 size_t length_writes = 1;
9602 if (read_write_round.extra_write) {
9603 writes[1] = *read_write_round.extra_write;
9604 length_writes = 2;
9605 }
9606 StaticSocketDataProvider data_provider(
9607 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079608 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159609
9610 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069611 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159612 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079613 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159614 &ssl_socket_data_provider);
9615
9616 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419617 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159618 int rv;
9619 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419620 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159621 } else {
[email protected]49639fa2011-12-20 23:22:419622 rv = trans.RestartWithAuth(
9623 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159624 }
9625 if (rv == ERR_IO_PENDING)
9626 rv = callback.WaitForResult();
9627
9628 // Compare results with expected data.
9629 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509630 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159631 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509632 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159633 } else {
9634 EXPECT_TRUE(response == NULL);
9635 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9636 continue;
9637 }
9638 if (round + 1 < test_config.num_auth_rounds) {
9639 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9640 } else {
9641 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9642 }
9643 }
[email protected]e5ae96a2010-04-14 20:12:459644 }
9645}
9646
[email protected]23e482282013-06-14 16:08:029647TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149648 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149649 HttpAuthHandlerMock::Factory* auth_factory(
9650 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079651 session_deps_.http_auth_handler_factory.reset(auth_factory);
9652 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9653 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9654 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149655
9656 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9657 auth_handler->set_connection_based(true);
9658 std::string auth_challenge = "Mock realm=server";
9659 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:249660 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9661 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:149662 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9663 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089664 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149665
[email protected]c871bce92010-07-15 21:51:149666 int rv = OK;
9667 const HttpResponseInfo* response = NULL;
9668 HttpRequestInfo request;
9669 request.method = "GET";
9670 request.url = origin;
9671 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279672
[email protected]bb88e1d32013-05-03 23:11:079673 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109674
9675 // Use a TCP Socket Pool with only one connection per group. This is used
9676 // to validate that the TCP socket is not released to the pool between
9677 // each round of multi-round authentication.
9678 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289679 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9680 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109681 50, // Max sockets for pool
9682 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289683 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079684 session_deps_.host_resolver.get(),
9685 session_deps_.socket_factory.get(),
9686 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449687 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9688 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029689 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449690 session_peer.SetClientSocketPoolManager(
9691 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109692
[email protected]262eec82013-03-19 21:01:369693 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509694 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419695 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149696
9697 const MockWrite kGet(
9698 "GET / HTTP/1.1\r\n"
9699 "Host: www.example.com\r\n"
9700 "Connection: keep-alive\r\n\r\n");
9701 const MockWrite kGetAuth(
9702 "GET / HTTP/1.1\r\n"
9703 "Host: www.example.com\r\n"
9704 "Connection: keep-alive\r\n"
9705 "Authorization: auth_token\r\n\r\n");
9706
9707 const MockRead kServerChallenge(
9708 "HTTP/1.1 401 Unauthorized\r\n"
9709 "WWW-Authenticate: Mock realm=server\r\n"
9710 "Content-Type: text/html; charset=iso-8859-1\r\n"
9711 "Content-Length: 14\r\n\r\n"
9712 "Unauthorized\r\n");
9713 const MockRead kSuccess(
9714 "HTTP/1.1 200 OK\r\n"
9715 "Content-Type: text/html; charset=iso-8859-1\r\n"
9716 "Content-Length: 3\r\n\r\n"
9717 "Yes");
9718
9719 MockWrite writes[] = {
9720 // First round
9721 kGet,
9722 // Second round
9723 kGetAuth,
9724 // Third round
9725 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309726 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109727 kGetAuth,
9728 // Competing request
9729 kGet,
[email protected]c871bce92010-07-15 21:51:149730 };
9731 MockRead reads[] = {
9732 // First round
9733 kServerChallenge,
9734 // Second round
9735 kServerChallenge,
9736 // Third round
[email protected]eca50e122010-09-11 14:03:309737 kServerChallenge,
9738 // Fourth round
[email protected]c871bce92010-07-15 21:51:149739 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109740 // Competing response
9741 kSuccess,
[email protected]c871bce92010-07-15 21:51:149742 };
9743 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9744 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079745 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149746
[email protected]7ef4cbbb2011-02-06 11:19:109747 const char* const kSocketGroup = "www.example.com:80";
9748
9749 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149750 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419751 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149752 if (rv == ERR_IO_PENDING)
9753 rv = callback.WaitForResult();
9754 EXPECT_EQ(OK, rv);
9755 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509756 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149757 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289758 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149759
[email protected]7ef4cbbb2011-02-06 11:19:109760 // In between rounds, another request comes in for the same domain.
9761 // It should not be able to grab the TCP socket that trans has already
9762 // claimed.
9763 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419765 TestCompletionCallback callback_compete;
9766 rv = trans_compete->Start(
9767 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109768 EXPECT_EQ(ERR_IO_PENDING, rv);
9769 // callback_compete.WaitForResult at this point would stall forever,
9770 // since the HttpNetworkTransaction does not release the request back to
9771 // the pool until after authentication completes.
9772
9773 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149774 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419775 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149776 if (rv == ERR_IO_PENDING)
9777 rv = callback.WaitForResult();
9778 EXPECT_EQ(OK, rv);
9779 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509780 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149781 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289782 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149783
[email protected]7ef4cbbb2011-02-06 11:19:109784 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149785 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419786 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149787 if (rv == ERR_IO_PENDING)
9788 rv = callback.WaitForResult();
9789 EXPECT_EQ(OK, rv);
9790 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509791 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149792 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289793 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309794
[email protected]7ef4cbbb2011-02-06 11:19:109795 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309796 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419797 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309798 if (rv == ERR_IO_PENDING)
9799 rv = callback.WaitForResult();
9800 EXPECT_EQ(OK, rv);
9801 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509802 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309803 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289804 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109805
9806 // Read the body since the fourth round was successful. This will also
9807 // release the socket back to the pool.
9808 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509809 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109810 if (rv == ERR_IO_PENDING)
9811 rv = callback.WaitForResult();
9812 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509813 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109814 EXPECT_EQ(0, rv);
9815 // There are still 0 idle sockets, since the trans_compete transaction
9816 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289817 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109818
9819 // The competing request can now finish. Wait for the headers and then
9820 // read the body.
9821 rv = callback_compete.WaitForResult();
9822 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509823 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109824 if (rv == ERR_IO_PENDING)
9825 rv = callback.WaitForResult();
9826 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509827 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109828 EXPECT_EQ(0, rv);
9829
9830 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289831 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149832}
9833
[email protected]65041fa2010-05-21 06:56:539834// This tests the case that a request is issued via http instead of spdy after
9835// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029836TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389837 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169838 std::vector<NextProto> next_protos;
9839 next_protos.push_back(kProtoHTTP11);
9840 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539841 HttpRequestInfo request;
9842 request.method = "GET";
9843 request.url = GURL("https://www.google.com/");
9844 request.load_flags = 0;
9845
9846 MockWrite data_writes[] = {
9847 MockWrite("GET / HTTP/1.1\r\n"
9848 "Host: www.google.com\r\n"
9849 "Connection: keep-alive\r\n\r\n"),
9850 };
9851
[email protected]8a0fc822013-06-27 20:52:439852 std::string alternate_protocol_http_header =
9853 GetAlternateProtocolHttpHeader();
9854
[email protected]65041fa2010-05-21 06:56:539855 MockRead data_reads[] = {
9856 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439857 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539858 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069859 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539860 };
9861
[email protected]8ddf8322012-02-23 18:08:069862 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539863 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9864 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469865 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539866
[email protected]bb88e1d32013-05-03 23:11:079867 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539868
9869 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9870 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539872
[email protected]49639fa2011-12-20 23:22:419873 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539874
[email protected]bb88e1d32013-05-03 23:11:079875 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369876 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539878
[email protected]49639fa2011-12-20 23:22:419879 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539880
9881 EXPECT_EQ(ERR_IO_PENDING, rv);
9882 EXPECT_EQ(OK, callback.WaitForResult());
9883
9884 const HttpResponseInfo* response = trans->GetResponseInfo();
9885 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509886 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539887 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9888
9889 std::string response_data;
9890 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9891 EXPECT_EQ("hello world", response_data);
9892
9893 EXPECT_FALSE(response->was_fetched_via_spdy);
9894 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539895}
[email protected]26ef6582010-06-24 02:30:479896
[email protected]23e482282013-06-14 16:08:029897TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479898 // Simulate the SSL handshake completing with an NPN negotiation
9899 // followed by an immediate server closing of the socket.
9900 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389901 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039902 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479903
9904 HttpRequestInfo request;
9905 request.method = "GET";
9906 request.url = GURL("https://www.google.com/");
9907 request.load_flags = 0;
9908
[email protected]8ddf8322012-02-23 18:08:069909 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029910 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079911 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479912
[email protected]cdf8f7e72013-05-23 10:56:469913 scoped_ptr<SpdyFrame> req(
9914 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139915 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479916
9917 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069918 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479919 };
9920
[email protected]dd54bd82012-07-19 23:44:579921 DelayedSocketData spdy_data(
9922 0, // don't wait in this case, immediate hangup.
9923 spdy_reads, arraysize(spdy_reads),
9924 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079925 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479926
[email protected]49639fa2011-12-20 23:22:419927 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479928
[email protected]bb88e1d32013-05-03 23:11:079929 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369930 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509931 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479932
[email protected]49639fa2011-12-20 23:22:419933 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479934 EXPECT_EQ(ERR_IO_PENDING, rv);
9935 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479936}
[email protected]65d34382010-07-01 18:12:269937
[email protected]795cbf82013-07-22 09:37:279938// A subclass of HttpAuthHandlerMock that records the request URL when
9939// it gets it. This is needed since the auth handler may get destroyed
9940// before we get a chance to query it.
9941class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9942 public:
9943 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9944
9945 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9946
9947 protected:
9948 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9949 const HttpRequestInfo* request,
9950 const CompletionCallback& callback,
9951 std::string* auth_token) OVERRIDE {
9952 *url_ = request->url;
9953 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9954 credentials, request, callback, auth_token);
9955 }
9956
9957 private:
9958 GURL* url_;
9959};
9960
[email protected]23e482282013-06-14 16:08:029961TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309962 // This test ensures that the URL passed into the proxy is upgraded
9963 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389964 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439965 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309966
[email protected]bb88e1d32013-05-03 23:11:079967 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209968 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9969 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079970 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279971 GURL request_url;
9972 {
9973 HttpAuthHandlerMock::Factory* auth_factory =
9974 new HttpAuthHandlerMock::Factory();
9975 UrlRecordingHttpAuthHandlerMock* auth_handler =
9976 new UrlRecordingHttpAuthHandlerMock(&request_url);
9977 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9978 auth_factory->set_do_init_from_challenge(true);
9979 session_deps_.http_auth_handler_factory.reset(auth_factory);
9980 }
[email protected]f45c1ee2010-08-03 00:54:309981
9982 HttpRequestInfo request;
9983 request.method = "GET";
9984 request.url = GURL("http://www.google.com");
9985 request.load_flags = 0;
9986
9987 // First round goes unauthenticated through the proxy.
9988 MockWrite data_writes_1[] = {
9989 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9990 "Host: www.google.com\r\n"
9991 "Proxy-Connection: keep-alive\r\n"
9992 "\r\n"),
9993 };
9994 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309996 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239997 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309998 "Proxy-Connection: close\r\n"
9999 "\r\n"),
10000 };
10001 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10002 data_writes_1, arraysize(data_writes_1));
10003
10004 // Second round tries to tunnel to www.google.com due to the
10005 // Alternate-Protocol announcement in the first round. It fails due
10006 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910007 // After the failure, a tunnel is established to www.google.com using
10008 // Proxy-Authorization headers. There is then a SPDY request round.
10009 //
[email protected]fe3b7dc2012-02-03 19:52:0910010 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10011 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10012 // does a Disconnect and Connect on the same socket, rather than trying
10013 // to obtain a new one.
10014 //
[email protected]394816e92010-08-03 07:38:5910015 // NOTE: Originally, the proxy response to the second CONNECT request
10016 // simply returned another 407 so the unit test could skip the SSL connection
10017 // establishment and SPDY framing issues. Alas, the
10018 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010019 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910020
[email protected]cdf8f7e72013-05-23 10:56:4610021 scoped_ptr<SpdyFrame> req(
10022 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210023 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10024 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010025
[email protected]394816e92010-08-03 07:38:5910026 MockWrite data_writes_2[] = {
10027 // First connection attempt without Proxy-Authorization.
10028 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10029 "Host: www.google.com\r\n"
10030 "Proxy-Connection: keep-alive\r\n"
10031 "\r\n"),
10032
10033 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010034 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10035 "Host: www.google.com\r\n"
10036 "Proxy-Connection: keep-alive\r\n"
10037 "Proxy-Authorization: auth_token\r\n"
10038 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010039
[email protected]394816e92010-08-03 07:38:5910040 // SPDY request
10041 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010042 };
[email protected]394816e92010-08-03 07:38:5910043 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10044 "Proxy-Authenticate: Mock\r\n"
10045 "Proxy-Connection: close\r\n"
10046 "\r\n");
10047 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10048 MockRead data_reads_2[] = {
10049 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610050 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10051 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910052 arraysize(kRejectConnectResponse) - 1, 1),
10053
10054 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610055 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910056 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910057
10058 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910059 CreateMockRead(*resp.get(), 6),
10060 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610061 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910062 };
[email protected]dd54bd82012-07-19 23:44:5710063 OrderedSocketData data_2(
10064 data_reads_2, arraysize(data_reads_2),
10065 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010066
[email protected]8ddf8322012-02-23 18:08:0610067 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210068 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010069
[email protected]d973e99a2012-02-17 21:02:3610070 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510071 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10072 NULL, 0, NULL, 0);
10073 hanging_non_alternate_protocol_socket.set_connect_data(
10074 never_finishing_connect);
10075
[email protected]bb88e1d32013-05-03 23:11:0710076 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10077 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10079 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510080 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710081 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010082
10083 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110084 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610085 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110087 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010088 EXPECT_EQ(ERR_IO_PENDING, rv);
10089 EXPECT_EQ(OK, callback_1.WaitForResult());
10090
10091 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110092 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610093 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110095 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010096 EXPECT_EQ(ERR_IO_PENDING, rv);
10097 EXPECT_EQ(OK, callback_2.WaitForResult());
10098 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010099 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010100 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10101
10102 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110103 TestCompletionCallback callback_3;
10104 rv = trans_2->RestartWithAuth(
10105 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010106 EXPECT_EQ(ERR_IO_PENDING, rv);
10107 EXPECT_EQ(OK, callback_3.WaitForResult());
10108
10109 // After all that work, these two lines (or actually, just the scheme) are
10110 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010111 EXPECT_EQ("https", request_url.scheme());
10112 EXPECT_EQ("www.google.com", request_url.host());
10113
[email protected]029c83b62013-01-24 05:28:2010114 LoadTimingInfo load_timing_info;
10115 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10116 TestLoadTimingNotReusedWithPac(load_timing_info,
10117 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810118}
10119
10120// Test that if we cancel the transaction as the connection is completing, that
10121// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210122TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810123 // Setup everything about the connection to complete synchronously, so that
10124 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10125 // for is the callback from the HttpStreamRequest.
10126 // Then cancel the transaction.
10127 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610128 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810129 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610130 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10131 MockRead(SYNCHRONOUS, "hello world"),
10132 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810133 };
10134
[email protected]8e6441ca2010-08-19 05:56:3810135 HttpRequestInfo request;
10136 request.method = "GET";
10137 request.url = GURL("http://www.google.com/");
10138 request.load_flags = 0;
10139
[email protected]bb88e1d32013-05-03 23:11:0710140 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710141 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710142 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0710143 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:2710144
[email protected]8e6441ca2010-08-19 05:56:3810145 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10146 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710147 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810148
[email protected]49639fa2011-12-20 23:22:4110149 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810150
[email protected]333bdf62012-06-08 22:57:2910151 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110152 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810153 EXPECT_EQ(ERR_IO_PENDING, rv);
10154 trans.reset(); // Cancel the transaction here.
10155
[email protected]2da659e2013-05-23 20:51:3410156 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010157}
10158
[email protected]76a505b2010-08-25 06:23:0010159// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210160TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710161 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010162 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910163 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710164 session_deps_.net_log = log.bound().net_log();
10165 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010166
[email protected]76a505b2010-08-25 06:23:0010167 HttpRequestInfo request;
10168 request.method = "GET";
10169 request.url = GURL("http://www.google.com/");
10170
10171 MockWrite data_writes1[] = {
10172 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10173 "Host: www.google.com\r\n"
10174 "Proxy-Connection: keep-alive\r\n\r\n"),
10175 };
10176
10177 MockRead data_reads1[] = {
10178 MockRead("HTTP/1.1 200 OK\r\n"),
10179 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10180 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610181 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010182 };
10183
10184 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10185 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710186 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010187
[email protected]49639fa2011-12-20 23:22:4110188 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010189
[email protected]262eec82013-03-19 21:01:3610190 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010192
[email protected]49639fa2011-12-20 23:22:4110193 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010194 EXPECT_EQ(ERR_IO_PENDING, rv);
10195
10196 rv = callback1.WaitForResult();
10197 EXPECT_EQ(OK, rv);
10198
10199 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010200 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010201
10202 EXPECT_TRUE(response->headers->IsKeepAlive());
10203 EXPECT_EQ(200, response->headers->response_code());
10204 EXPECT_EQ(100, response->headers->GetContentLength());
10205 EXPECT_TRUE(response->was_fetched_via_proxy);
10206 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010207
10208 LoadTimingInfo load_timing_info;
10209 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10210 TestLoadTimingNotReusedWithPac(load_timing_info,
10211 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010212}
10213
10214// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210215TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710216 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010217 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910218 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710219 session_deps_.net_log = log.bound().net_log();
10220 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010221
[email protected]76a505b2010-08-25 06:23:0010222 HttpRequestInfo request;
10223 request.method = "GET";
10224 request.url = GURL("https://www.google.com/");
10225
10226 // Since we have proxy, should try to establish tunnel.
10227 MockWrite data_writes1[] = {
10228 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10229 "Host: www.google.com\r\n"
10230 "Proxy-Connection: keep-alive\r\n\r\n"),
10231
10232 MockWrite("GET / HTTP/1.1\r\n"
10233 "Host: www.google.com\r\n"
10234 "Connection: keep-alive\r\n\r\n"),
10235 };
10236
10237 MockRead data_reads1[] = {
10238 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10239
10240 MockRead("HTTP/1.1 200 OK\r\n"),
10241 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10242 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610243 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010244 };
10245
10246 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10247 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710248 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610249 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010251
[email protected]49639fa2011-12-20 23:22:4110252 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010253
[email protected]262eec82013-03-19 21:01:3610254 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010256
[email protected]49639fa2011-12-20 23:22:4110257 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010258 EXPECT_EQ(ERR_IO_PENDING, rv);
10259
10260 rv = callback1.WaitForResult();
10261 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710262 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010263 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010264 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010265 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010266 NetLog::PHASE_NONE);
10267 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010268 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010269 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10270 NetLog::PHASE_NONE);
10271
10272 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010273 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010274
10275 EXPECT_TRUE(response->headers->IsKeepAlive());
10276 EXPECT_EQ(200, response->headers->response_code());
10277 EXPECT_EQ(100, response->headers->GetContentLength());
10278 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10279 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:2010280
10281 LoadTimingInfo load_timing_info;
10282 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10283 TestLoadTimingNotReusedWithPac(load_timing_info,
10284 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010285}
10286
10287// Test a basic HTTPS GET request through a proxy, but the server hangs up
10288// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210289TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710290 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910291 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710292 session_deps_.net_log = log.bound().net_log();
10293 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010294
[email protected]76a505b2010-08-25 06:23:0010295 HttpRequestInfo request;
10296 request.method = "GET";
10297 request.url = GURL("https://www.google.com/");
10298
10299 // Since we have proxy, should try to establish tunnel.
10300 MockWrite data_writes1[] = {
10301 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10302 "Host: www.google.com\r\n"
10303 "Proxy-Connection: keep-alive\r\n\r\n"),
10304
10305 MockWrite("GET / HTTP/1.1\r\n"
10306 "Host: www.google.com\r\n"
10307 "Connection: keep-alive\r\n\r\n"),
10308 };
10309
10310 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610311 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010312 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610313 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010314 };
10315
10316 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10317 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710318 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610319 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710320 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010321
[email protected]49639fa2011-12-20 23:22:4110322 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010323
[email protected]262eec82013-03-19 21:01:3610324 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010326
[email protected]49639fa2011-12-20 23:22:4110327 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010328 EXPECT_EQ(ERR_IO_PENDING, rv);
10329
10330 rv = callback1.WaitForResult();
10331 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710332 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010333 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010334 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010335 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010336 NetLog::PHASE_NONE);
10337 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010338 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010339 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10340 NetLog::PHASE_NONE);
10341}
10342
[email protected]749eefa82010-09-13 22:14:0310343// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210344TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610345 scoped_ptr<SpdyFrame> req(
10346 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310347 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10348
[email protected]23e482282013-06-14 16:08:0210349 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10350 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310351 MockRead spdy_reads[] = {
10352 CreateMockRead(*resp),
10353 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610354 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310355 };
10356
[email protected]dd54bd82012-07-19 23:44:5710357 DelayedSocketData spdy_data(
10358 1, // wait for one write to finish before reading.
10359 spdy_reads, arraysize(spdy_reads),
10360 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710361 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310362
[email protected]8ddf8322012-02-23 18:08:0610363 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210364 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310366
[email protected]bb88e1d32013-05-03 23:11:0710367 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310368
10369 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810370 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010371 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310372 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710373 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610374 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310375
10376 HttpRequestInfo request;
10377 request.method = "GET";
10378 request.url = GURL("https://www.google.com/");
10379 request.load_flags = 0;
10380
10381 // This is the important line that marks this as a preconnect.
10382 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10383
[email protected]262eec82013-03-19 21:01:3610384 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310386
[email protected]41d64e82013-07-03 22:44:2610387 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310389 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110390 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310391}
10392
[email protected]73b8dd222010-11-11 19:55:2410393// Given a net error, cause that error to be returned from the first Write()
10394// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210395void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710396 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710397 net::HttpRequestInfo request_info;
10398 request_info.url = GURL("https://www.example.com/");
10399 request_info.method = "GET";
10400 request_info.load_flags = net::LOAD_NORMAL;
10401
[email protected]8ddf8322012-02-23 18:08:0610402 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410403 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610404 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410405 };
10406 net::StaticSocketDataProvider data(NULL, 0,
10407 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710408 session_deps_.socket_factory->AddSocketDataProvider(&data);
10409 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410410
[email protected]bb88e1d32013-05-03 23:11:0710411 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610412 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010413 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410414
[email protected]49639fa2011-12-20 23:22:4110415 TestCompletionCallback callback;
10416 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410417 if (rv == net::ERR_IO_PENDING)
10418 rv = callback.WaitForResult();
10419 ASSERT_EQ(error, rv);
10420}
10421
[email protected]23e482282013-06-14 16:08:0210422TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410423 // Just check a grab bag of cert errors.
10424 static const int kErrors[] = {
10425 ERR_CERT_COMMON_NAME_INVALID,
10426 ERR_CERT_AUTHORITY_INVALID,
10427 ERR_CERT_DATE_INVALID,
10428 };
10429 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610430 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10431 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410432 }
10433}
10434
[email protected]bd0b6772011-01-11 19:59:3010435// Ensure that a client certificate is removed from the SSL client auth
10436// cache when:
10437// 1) No proxy is involved.
10438// 2) TLS False Start is disabled.
10439// 3) The initial TLS handshake requests a client certificate.
10440// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210441TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310442 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710443 net::HttpRequestInfo request_info;
10444 request_info.url = GURL("https://www.example.com/");
10445 request_info.method = "GET";
10446 request_info.load_flags = net::LOAD_NORMAL;
10447
[email protected]bd0b6772011-01-11 19:59:3010448 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110449 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010450
10451 // [ssl_]data1 contains the data for the first SSL handshake. When a
10452 // CertificateRequest is received for the first time, the handshake will
10453 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610454 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010455 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010457 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710458 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010459
10460 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10461 // False Start is not being used, the result of the SSL handshake will be
10462 // returned as part of the SSLClientSocket::Connect() call. This test
10463 // matches the result of a server sending a handshake_failure alert,
10464 // rather than a Finished message, because it requires a client
10465 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610466 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010467 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010469 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710470 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010471
10472 // [ssl_]data3 contains the data for the third SSL handshake. When a
10473 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710474 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10475 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010476 // of the HttpNetworkTransaction. Because this test failure is due to
10477 // requiring a client certificate, this fallback handshake should also
10478 // fail.
[email protected]8ddf8322012-02-23 18:08:0610479 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010480 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010482 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710483 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010484
[email protected]80c75f682012-05-26 16:22:1710485 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10486 // connection to a server fails during an SSL handshake,
10487 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10488 // connection was attempted with TLSv1. This is transparent to the caller
10489 // of the HttpNetworkTransaction. Because this test failure is due to
10490 // requiring a client certificate, this fallback handshake should also
10491 // fail.
10492 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10493 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710494 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710495 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710496 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710497
[email protected]7799de12013-05-30 05:52:5110498 // Need one more if TLSv1.2 is enabled.
10499 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10500 ssl_data5.cert_request_info = cert_request.get();
10501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10502 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10503 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10504
[email protected]bb88e1d32013-05-03 23:11:0710505 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610506 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010507 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010508
[email protected]bd0b6772011-01-11 19:59:3010509 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110510 TestCompletionCallback callback;
10511 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010512 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10513
10514 // Complete the SSL handshake, which should abort due to requiring a
10515 // client certificate.
10516 rv = callback.WaitForResult();
10517 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10518
10519 // Indicate that no certificate should be supplied. From the perspective
10520 // of SSLClientCertCache, NULL is just as meaningful as a real
10521 // certificate, so this is the same as supply a
10522 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110523 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010524 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10525
10526 // Ensure the certificate was added to the client auth cache before
10527 // allowing the connection to continue restarting.
10528 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110529 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10530 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010531 ASSERT_EQ(NULL, client_cert.get());
10532
10533 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710534 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10535 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010536 rv = callback.WaitForResult();
10537 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10538
10539 // Ensure that the client certificate is removed from the cache on a
10540 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110541 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10542 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010543}
10544
10545// Ensure that a client certificate is removed from the SSL client auth
10546// cache when:
10547// 1) No proxy is involved.
10548// 2) TLS False Start is enabled.
10549// 3) The initial TLS handshake requests a client certificate.
10550// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210551TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310552 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710553 net::HttpRequestInfo request_info;
10554 request_info.url = GURL("https://www.example.com/");
10555 request_info.method = "GET";
10556 request_info.load_flags = net::LOAD_NORMAL;
10557
[email protected]bd0b6772011-01-11 19:59:3010558 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110559 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010560
10561 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10562 // return successfully after reading up to the peer's Certificate message.
10563 // This is to allow the caller to call SSLClientSocket::Write(), which can
10564 // enqueue application data to be sent in the same packet as the
10565 // ChangeCipherSpec and Finished messages.
10566 // The actual handshake will be finished when SSLClientSocket::Read() is
10567 // called, which expects to process the peer's ChangeCipherSpec and
10568 // Finished messages. If there was an error negotiating with the peer,
10569 // such as due to the peer requiring a client certificate when none was
10570 // supplied, the alert sent by the peer won't be processed until Read() is
10571 // called.
10572
10573 // Like the non-False Start case, when a client certificate is requested by
10574 // the peer, the handshake is aborted during the Connect() call.
10575 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610576 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010577 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710578 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010579 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710580 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010581
10582 // When a client certificate is supplied, Connect() will not be aborted
10583 // when the peer requests the certificate. Instead, the handshake will
10584 // artificially succeed, allowing the caller to write the HTTP request to
10585 // the socket. The handshake messages are not processed until Read() is
10586 // called, which then detects that the handshake was aborted, due to the
10587 // peer sending a handshake_failure because it requires a client
10588 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610589 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010590 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710591 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010592 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610593 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010594 };
10595 net::StaticSocketDataProvider data2(
10596 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710597 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010598
10599 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710600 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10601 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610602 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010603 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710604 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010605 net::StaticSocketDataProvider data3(
10606 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710607 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010608
[email protected]80c75f682012-05-26 16:22:1710609 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10610 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10611 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10612 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710614 net::StaticSocketDataProvider data4(
10615 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710616 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710617
[email protected]7799de12013-05-30 05:52:5110618 // Need one more if TLSv1.2 is enabled.
10619 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10620 ssl_data5.cert_request_info = cert_request.get();
10621 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10622 net::StaticSocketDataProvider data5(
10623 data2_reads, arraysize(data2_reads), NULL, 0);
10624 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10625
[email protected]bb88e1d32013-05-03 23:11:0710626 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610627 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010628 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010629
[email protected]bd0b6772011-01-11 19:59:3010630 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110631 TestCompletionCallback callback;
10632 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010633 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10634
10635 // Complete the SSL handshake, which should abort due to requiring a
10636 // client certificate.
10637 rv = callback.WaitForResult();
10638 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10639
10640 // Indicate that no certificate should be supplied. From the perspective
10641 // of SSLClientCertCache, NULL is just as meaningful as a real
10642 // certificate, so this is the same as supply a
10643 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110644 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010645 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10646
10647 // Ensure the certificate was added to the client auth cache before
10648 // allowing the connection to continue restarting.
10649 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110650 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10651 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010652 ASSERT_EQ(NULL, client_cert.get());
10653
[email protected]bd0b6772011-01-11 19:59:3010654 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710655 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10656 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010657 rv = callback.WaitForResult();
10658 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10659
10660 // Ensure that the client certificate is removed from the cache on a
10661 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110662 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10663 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010664}
10665
[email protected]8c405132011-01-11 22:03:1810666// Ensure that a client certificate is removed from the SSL client auth
10667// cache when:
10668// 1) An HTTPS proxy is involved.
10669// 3) The HTTPS proxy requests a client certificate.
10670// 4) The client supplies an invalid/unacceptable certificate for the
10671// proxy.
10672// The test is repeated twice, first for connecting to an HTTPS endpoint,
10673// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210674TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710675 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810676 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910677 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710678 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810679
10680 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110681 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810682
10683 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10684 // [ssl_]data[1-3]. Rather than represending the endpoint
10685 // (www.example.com:443), they represent failures with the HTTPS proxy
10686 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610687 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810688 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710689 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810690 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710691 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810692
[email protected]8ddf8322012-02-23 18:08:0610693 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810694 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710695 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810696 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710697 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810698
[email protected]80c75f682012-05-26 16:22:1710699 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10700#if 0
[email protected]8ddf8322012-02-23 18:08:0610701 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810702 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810704 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710705 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710706#endif
[email protected]8c405132011-01-11 22:03:1810707
10708 net::HttpRequestInfo requests[2];
10709 requests[0].url = GURL("https://www.example.com/");
10710 requests[0].method = "GET";
10711 requests[0].load_flags = net::LOAD_NORMAL;
10712
10713 requests[1].url = GURL("http://www.example.com/");
10714 requests[1].method = "GET";
10715 requests[1].load_flags = net::LOAD_NORMAL;
10716
10717 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710718 session_deps_.socket_factory->ResetNextMockIndexes();
10719 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810720 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010721 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810722
10723 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110724 TestCompletionCallback callback;
10725 int rv = trans->Start(
10726 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810727 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10728
10729 // Complete the SSL handshake, which should abort due to requiring a
10730 // client certificate.
10731 rv = callback.WaitForResult();
10732 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10733
10734 // Indicate that no certificate should be supplied. From the perspective
10735 // of SSLClientCertCache, NULL is just as meaningful as a real
10736 // certificate, so this is the same as supply a
10737 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110738 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810739 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10740
10741 // Ensure the certificate was added to the client auth cache before
10742 // allowing the connection to continue restarting.
10743 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110744 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10745 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810746 ASSERT_EQ(NULL, client_cert.get());
10747 // Ensure the certificate was NOT cached for the endpoint. This only
10748 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110749 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10750 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810751
10752 // Restart the handshake. This will consume ssl_data2, which fails, and
10753 // then consume ssl_data3, which should also fail. The result code is
10754 // checked against what ssl_data3 should return.
10755 rv = callback.WaitForResult();
10756 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10757
10758 // Now that the new handshake has failed, ensure that the client
10759 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110760 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10761 HostPortPair("proxy", 70), &client_cert));
10762 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10763 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810764 }
10765}
10766
[email protected]23e482282013-06-14 16:08:0210767// Unlike TEST/TEST_F, which are macros that expand to further macros,
10768// TEST_P is a macro that expands directly to code that stringizes the
10769// arguments. As a result, macros passed as parameters (such as prefix
10770// or test_case_name) will not be expanded by the preprocessor. To
10771// work around this, indirect the macro for TEST_P, so that the
10772// pre-processor will expand macros such as MAYBE_test_name before
10773// instantiating the test.
10774#define WRAPPED_TEST_P(test_case_name, test_name) \
10775 TEST_P(test_case_name, test_name)
10776
[email protected]45b170822012-05-04 21:18:1410777// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10778#if defined(OS_WIN)
10779#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10780#else
10781#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10782#endif
[email protected]23e482282013-06-14 16:08:0210783WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610784 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310785 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610786
10787 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710788 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610790 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10791 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610792
[email protected]8ddf8322012-02-23 18:08:0610793 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210794 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610796
[email protected]cdf8f7e72013-05-23 10:56:4610797 scoped_ptr<SpdyFrame> host1_req(
10798 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10799 scoped_ptr<SpdyFrame> host2_req(
10800 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610801 MockWrite spdy_writes[] = {
10802 CreateMockWrite(*host1_req, 1),
10803 CreateMockWrite(*host2_req, 4),
10804 };
[email protected]23e482282013-06-14 16:08:0210805 scoped_ptr<SpdyFrame> host1_resp(
10806 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10807 scoped_ptr<SpdyFrame> host1_resp_body(
10808 spdy_util_.ConstructSpdyBodyFrame(1, true));
10809 scoped_ptr<SpdyFrame> host2_resp(
10810 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10811 scoped_ptr<SpdyFrame> host2_resp_body(
10812 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610813 MockRead spdy_reads[] = {
10814 CreateMockRead(*host1_resp, 2),
10815 CreateMockRead(*host1_resp_body, 3),
10816 CreateMockRead(*host2_resp, 5),
10817 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610818 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610819 };
10820
[email protected]d2b5f092012-06-08 23:55:0210821 IPAddressNumber ip;
10822 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10823 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10824 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710825 OrderedSocketData spdy_data(
10826 connect,
10827 spdy_reads, arraysize(spdy_reads),
10828 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710829 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610830
[email protected]aa22b242011-11-16 18:58:2910831 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610832 HttpRequestInfo request1;
10833 request1.method = "GET";
10834 request1.url = GURL("https://www.google.com/");
10835 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010836 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610837
[email protected]49639fa2011-12-20 23:22:4110838 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610839 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110840 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610841
10842 const HttpResponseInfo* response = trans1.GetResponseInfo();
10843 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010844 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610845 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10846
10847 std::string response_data;
10848 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10849 EXPECT_EQ("hello!", response_data);
10850
10851 // Preload www.gmail.com into HostCache.
10852 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010853 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610854 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010855 rv = session_deps_.host_resolver->Resolve(resolve_info,
10856 DEFAULT_PRIORITY,
10857 &ignored,
10858 callback.callback(),
10859 NULL,
10860 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710861 EXPECT_EQ(ERR_IO_PENDING, rv);
10862 rv = callback.WaitForResult();
10863 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610864
10865 HttpRequestInfo request2;
10866 request2.method = "GET";
10867 request2.url = GURL("https://www.gmail.com/");
10868 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010869 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610870
[email protected]49639fa2011-12-20 23:22:4110871 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610872 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110873 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610874
10875 response = trans2.GetResponseInfo();
10876 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010877 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610878 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10879 EXPECT_TRUE(response->was_fetched_via_spdy);
10880 EXPECT_TRUE(response->was_npn_negotiated);
10881 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10882 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610883}
[email protected]45b170822012-05-04 21:18:1410884#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610885
[email protected]23e482282013-06-14 16:08:0210886TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210887 HttpStreamFactory::set_use_alternate_protocols(true);
10888 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10889
10890 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710891 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10892 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210893 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10894 pool_peer.DisableDomainAuthenticationVerification();
10895
10896 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210897 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710898 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210899
[email protected]cdf8f7e72013-05-23 10:56:4610900 scoped_ptr<SpdyFrame> host1_req(
10901 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10902 scoped_ptr<SpdyFrame> host2_req(
10903 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210904 MockWrite spdy_writes[] = {
10905 CreateMockWrite(*host1_req, 1),
10906 CreateMockWrite(*host2_req, 4),
10907 };
[email protected]23e482282013-06-14 16:08:0210908 scoped_ptr<SpdyFrame> host1_resp(
10909 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10910 scoped_ptr<SpdyFrame> host1_resp_body(
10911 spdy_util_.ConstructSpdyBodyFrame(1, true));
10912 scoped_ptr<SpdyFrame> host2_resp(
10913 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10914 scoped_ptr<SpdyFrame> host2_resp_body(
10915 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210916 MockRead spdy_reads[] = {
10917 CreateMockRead(*host1_resp, 2),
10918 CreateMockRead(*host1_resp_body, 3),
10919 CreateMockRead(*host2_resp, 5),
10920 CreateMockRead(*host2_resp_body, 6),
10921 MockRead(ASYNC, 0, 7),
10922 };
10923
10924 IPAddressNumber ip;
10925 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10926 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10927 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710928 OrderedSocketData spdy_data(
10929 connect,
10930 spdy_reads, arraysize(spdy_reads),
10931 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710932 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210933
10934 TestCompletionCallback callback;
10935 HttpRequestInfo request1;
10936 request1.method = "GET";
10937 request1.url = GURL("https://www.google.com/");
10938 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010939 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210940
10941 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10942 EXPECT_EQ(ERR_IO_PENDING, rv);
10943 EXPECT_EQ(OK, callback.WaitForResult());
10944
10945 const HttpResponseInfo* response = trans1.GetResponseInfo();
10946 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010947 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210948 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10949
10950 std::string response_data;
10951 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10952 EXPECT_EQ("hello!", response_data);
10953
10954 HttpRequestInfo request2;
10955 request2.method = "GET";
10956 request2.url = GURL("https://www.gmail.com/");
10957 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010958 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210959
10960 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10961 EXPECT_EQ(ERR_IO_PENDING, rv);
10962 EXPECT_EQ(OK, callback.WaitForResult());
10963
10964 response = trans2.GetResponseInfo();
10965 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010966 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210967 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10968 EXPECT_TRUE(response->was_fetched_via_spdy);
10969 EXPECT_TRUE(response->was_npn_negotiated);
10970 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10971 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210972}
10973
[email protected]e3ceb682011-06-28 23:55:4610974class OneTimeCachingHostResolver : public net::HostResolver {
10975 public:
10976 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10977 : host_port_(host_port) {}
10978 virtual ~OneTimeCachingHostResolver() {}
10979
10980 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10981
10982 // HostResolver methods:
10983 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010984 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610985 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910986 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610987 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010988 const BoundNetLog& net_log) OVERRIDE {
10989 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010990 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010991 }
10992
10993 virtual int ResolveFromCache(const RequestInfo& info,
10994 AddressList* addresses,
10995 const BoundNetLog& net_log) OVERRIDE {
10996 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10997 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910998 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610999 return rv;
11000 }
11001
[email protected]95a214c2011-08-04 21:50:4011002 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4611003 host_resolver_.CancelRequest(req);
11004 }
11005
[email protected]46da33be2011-07-19 21:58:0411006 MockCachingHostResolver* GetMockHostResolver() {
11007 return &host_resolver_;
11008 }
11009
[email protected]e3ceb682011-06-28 23:55:4611010 private:
11011 MockCachingHostResolver host_resolver_;
11012 const HostPortPair host_port_;
11013};
11014
[email protected]45b170822012-05-04 21:18:1411015// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11016#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711017#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11018 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411019#else
[email protected]bb88e1d32013-05-03 23:11:0711020#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11021 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411022#endif
[email protected]23e482282013-06-14 16:08:0211023WRAPPED_TEST_P(HttpNetworkTransactionTest,
11024 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211025// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11026// prefix doesn't work with parametrized tests).
11027#if defined(OS_WIN)
11028 return;
[email protected]88c7b4be2014-03-19 23:04:0111029#else
[email protected]e3ceb682011-06-28 23:55:4611030 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0311031 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4611032
11033 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611034 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411035 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711036 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611037 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711038 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611039 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11040 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611041
[email protected]8ddf8322012-02-23 18:08:0611042 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211043 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611045
[email protected]cdf8f7e72013-05-23 10:56:4611046 scoped_ptr<SpdyFrame> host1_req(
11047 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11048 scoped_ptr<SpdyFrame> host2_req(
11049 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611050 MockWrite spdy_writes[] = {
11051 CreateMockWrite(*host1_req, 1),
11052 CreateMockWrite(*host2_req, 4),
11053 };
[email protected]23e482282013-06-14 16:08:0211054 scoped_ptr<SpdyFrame> host1_resp(
11055 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11056 scoped_ptr<SpdyFrame> host1_resp_body(
11057 spdy_util_.ConstructSpdyBodyFrame(1, true));
11058 scoped_ptr<SpdyFrame> host2_resp(
11059 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11060 scoped_ptr<SpdyFrame> host2_resp_body(
11061 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611062 MockRead spdy_reads[] = {
11063 CreateMockRead(*host1_resp, 2),
11064 CreateMockRead(*host1_resp_body, 3),
11065 CreateMockRead(*host2_resp, 5),
11066 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611067 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611068 };
11069
[email protected]d2b5f092012-06-08 23:55:0211070 IPAddressNumber ip;
11071 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11072 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11073 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711074 OrderedSocketData spdy_data(
11075 connect,
11076 spdy_reads, arraysize(spdy_reads),
11077 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711078 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611079
[email protected]aa22b242011-11-16 18:58:2911080 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611081 HttpRequestInfo request1;
11082 request1.method = "GET";
11083 request1.url = GURL("https://www.google.com/");
11084 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011085 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611086
[email protected]49639fa2011-12-20 23:22:4111087 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611088 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111089 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611090
11091 const HttpResponseInfo* response = trans1.GetResponseInfo();
11092 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011093 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611094 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11095
11096 std::string response_data;
11097 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11098 EXPECT_EQ("hello!", response_data);
11099
11100 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011101 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611102 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011103 rv = host_resolver.Resolve(resolve_info,
11104 DEFAULT_PRIORITY,
11105 &ignored,
11106 callback.callback(),
11107 NULL,
11108 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711109 EXPECT_EQ(ERR_IO_PENDING, rv);
11110 rv = callback.WaitForResult();
11111 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611112
11113 HttpRequestInfo request2;
11114 request2.method = "GET";
11115 request2.url = GURL("https://www.gmail.com/");
11116 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011117 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611118
[email protected]49639fa2011-12-20 23:22:4111119 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611120 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111121 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611122
11123 response = trans2.GetResponseInfo();
11124 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011125 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611126 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11127 EXPECT_TRUE(response->was_fetched_via_spdy);
11128 EXPECT_TRUE(response->was_npn_negotiated);
11129 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11130 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111131#endif
[email protected]e3ceb682011-06-28 23:55:4611132}
[email protected]45b170822012-05-04 21:18:1411133#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611134
[email protected]23e482282013-06-14 16:08:0211135TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2911136 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611137 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2911138 };
11139 MockRead data_reads2[] = {
11140 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11141 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611142 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2911143 };
11144 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
11145 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
11146 StaticSocketDataProvider* data[] = { &data1, &data2 };
11147
11148 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
11149
11150 EXPECT_EQ(OK, out.rv);
11151 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
11152 EXPECT_EQ("hello world", out.response_data);
11153}
11154
[email protected]23e482282013-06-14 16:08:0211155TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2911156 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0611157 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2911158 };
11159 MockWrite data_writes2[] = {
11160 MockWrite("GET / HTTP/1.1\r\n"
11161 "Host: www.google.com\r\n"
11162 "Connection: keep-alive\r\n\r\n"),
11163 };
11164 MockRead data_reads2[] = {
11165 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11166 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611167 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2911168 };
11169 StaticSocketDataProvider data1(NULL, 0,
11170 data_writes1, arraysize(data_writes1));
11171 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
11172 data_writes2, arraysize(data_writes2));
11173 StaticSocketDataProvider* data[] = { &data1, &data2 };
11174
11175 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
11176
11177 EXPECT_EQ(OK, out.rv);
11178 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
11179 EXPECT_EQ("hello world", out.response_data);
11180}
11181
[email protected]23e482282013-06-14 16:08:0211182TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0411183 const std::string https_url = "https://www.google.com/";
11184 const std::string http_url = "http://www.google.com:443/";
11185
11186 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611187 scoped_ptr<SpdyFrame> req1(
11188 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411189
11190 MockWrite writes1[] = {
11191 CreateMockWrite(*req1, 0),
11192 };
11193
[email protected]23e482282013-06-14 16:08:0211194 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11195 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411196 MockRead reads1[] = {
11197 CreateMockRead(*resp1, 1),
11198 CreateMockRead(*body1, 2),
11199 MockRead(ASYNC, ERR_IO_PENDING, 3)
11200 };
11201
[email protected]dd54bd82012-07-19 23:44:5711202 DelayedSocketData data1(
11203 1, reads1, arraysize(reads1),
11204 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411205 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711206 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411207
11208 // HTTP GET for the HTTP URL
11209 MockWrite writes2[] = {
11210 MockWrite(ASYNC, 4,
11211 "GET / HTTP/1.1\r\n"
11212 "Host: www.google.com:443\r\n"
11213 "Connection: keep-alive\r\n\r\n"),
11214 };
11215
11216 MockRead reads2[] = {
11217 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11218 MockRead(ASYNC, 6, "hello"),
11219 MockRead(ASYNC, 7, OK),
11220 };
11221
[email protected]dd54bd82012-07-19 23:44:5711222 DelayedSocketData data2(
11223 1, reads2, arraysize(reads2),
11224 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411225
[email protected]8450d722012-07-02 19:14:0411226 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211227 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711228 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11229 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11230 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411231
[email protected]bb88e1d32013-05-03 23:11:0711232 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411233
11234 // Start the first transaction to set up the SpdySession
11235 HttpRequestInfo request1;
11236 request1.method = "GET";
11237 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411238 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011239 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411240 TestCompletionCallback callback1;
11241 EXPECT_EQ(ERR_IO_PENDING,
11242 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411243 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411244
11245 EXPECT_EQ(OK, callback1.WaitForResult());
11246 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11247
11248 // Now, start the HTTP request
11249 HttpRequestInfo request2;
11250 request2.method = "GET";
11251 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411252 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011253 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411254 TestCompletionCallback callback2;
11255 EXPECT_EQ(ERR_IO_PENDING,
11256 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411257 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411258
11259 EXPECT_EQ(OK, callback2.WaitForResult());
11260 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11261}
11262
[email protected]23e482282013-06-14 16:08:0211263TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0411264 const std::string https_url = "https://www.google.com/";
11265 const std::string http_url = "http://www.google.com:443/";
11266
11267 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5411268 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11269 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611270 scoped_ptr<SpdyFrame> req1(
11271 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211272 scoped_ptr<SpdyFrame> wrapped_req1(
11273 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911274
11275 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
11276 SpdySynStreamIR req2_ir(3);
11277 spdy_util_.SetPriority(MEDIUM, &req2_ir);
11278 req2_ir.set_fin(true);
11279 req2_ir.SetHeader(spdy_util_.GetMethodKey(), "GET");
11280 req2_ir.SetHeader(spdy_util_.GetPathKey(),
11281 spdy_util_.is_spdy2() ? http_url.c_str() : "/");
11282 req2_ir.SetHeader(spdy_util_.GetHostKey(), "www.google.com:443");
11283 req2_ir.SetHeader(spdy_util_.GetSchemeKey(), "http");
11284 spdy_util_.MaybeAddVersionHeader(&req2_ir);
11285 scoped_ptr<SpdyFrame> req2(
11286 spdy_util_.CreateFramer(false)->SerializeFrame(req2_ir));
[email protected]8450d722012-07-02 19:14:0411287
11288 MockWrite writes1[] = {
11289 CreateMockWrite(*connect, 0),
11290 CreateMockWrite(*wrapped_req1, 2),
11291 CreateMockWrite(*req2, 5),
11292 };
11293
[email protected]23e482282013-06-14 16:08:0211294 scoped_ptr<SpdyFrame> conn_resp(
11295 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11296 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11297 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11298 scoped_ptr<SpdyFrame> wrapped_resp1(
11299 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11300 scoped_ptr<SpdyFrame> wrapped_body1(
11301 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11302 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11303 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411304 MockRead reads1[] = {
11305 CreateMockRead(*conn_resp, 1),
11306 CreateMockRead(*wrapped_resp1, 3),
11307 CreateMockRead(*wrapped_body1, 4),
11308 CreateMockRead(*resp2, 6),
11309 CreateMockRead(*body2, 7),
11310 MockRead(ASYNC, ERR_IO_PENDING, 8)
11311 };
11312
[email protected]dd54bd82012-07-19 23:44:5711313 DeterministicSocketData data1(reads1, arraysize(reads1),
11314 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411315 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711316 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411317
[email protected]bb88e1d32013-05-03 23:11:0711318 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211319 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11320 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711321 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411322 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211323 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711324 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411325 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211326 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711327 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11328 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411329
11330 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711331 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411332
11333 // Start the first transaction to set up the SpdySession
11334 HttpRequestInfo request1;
11335 request1.method = "GET";
11336 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411337 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011338 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411339 TestCompletionCallback callback1;
11340 EXPECT_EQ(ERR_IO_PENDING,
11341 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411342 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711343 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411344
11345 EXPECT_EQ(OK, callback1.WaitForResult());
11346 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11347
[email protected]f6c63db52013-02-02 00:35:2211348 LoadTimingInfo load_timing_info1;
11349 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11350 TestLoadTimingNotReusedWithPac(load_timing_info1,
11351 CONNECT_TIMING_HAS_SSL_TIMES);
11352
[email protected]8450d722012-07-02 19:14:0411353 // Now, start the HTTP request
11354 HttpRequestInfo request2;
11355 request2.method = "GET";
11356 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411357 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011358 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411359 TestCompletionCallback callback2;
11360 EXPECT_EQ(ERR_IO_PENDING,
11361 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411362 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711363 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411364
11365 EXPECT_EQ(OK, callback2.WaitForResult());
11366 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211367
11368 LoadTimingInfo load_timing_info2;
11369 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11370 // The established SPDY sessions is considered reused by the HTTP request.
11371 TestLoadTimingReusedWithPac(load_timing_info2);
11372 // HTTP requests over a SPDY session should have a different connection
11373 // socket_log_id than requests over a tunnel.
11374 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411375}
11376
[email protected]23e482282013-06-14 16:08:0211377TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411378 HttpStreamFactory::set_force_spdy_always(true);
11379 const std::string https_url = "https://www.google.com/";
11380 const std::string http_url = "http://www.google.com:443/";
11381
11382 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611383 scoped_ptr<SpdyFrame> req1(
11384 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411385 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611386 scoped_ptr<SpdyFrame> req2(
11387 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411388
11389 MockWrite writes[] = {
11390 CreateMockWrite(*req1, 1),
11391 CreateMockWrite(*req2, 4),
11392 };
11393
[email protected]23e482282013-06-14 16:08:0211394 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11395 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11396 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11397 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411398 MockRead reads[] = {
11399 CreateMockRead(*resp1, 2),
11400 CreateMockRead(*body1, 3),
11401 CreateMockRead(*resp2, 5),
11402 CreateMockRead(*body2, 6),
11403 MockRead(ASYNC, ERR_IO_PENDING, 7)
11404 };
11405
[email protected]dd54bd82012-07-19 23:44:5711406 OrderedSocketData data(reads, arraysize(reads),
11407 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411408
[email protected]8450d722012-07-02 19:14:0411409 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211410 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711411 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11412 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411413
[email protected]bb88e1d32013-05-03 23:11:0711414 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411415
11416 // Start the first transaction to set up the SpdySession
11417 HttpRequestInfo request1;
11418 request1.method = "GET";
11419 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411420 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011421 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411422 TestCompletionCallback callback1;
11423 EXPECT_EQ(ERR_IO_PENDING,
11424 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411425 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411426
11427 EXPECT_EQ(OK, callback1.WaitForResult());
11428 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11429
11430 // Now, start the HTTP request
11431 HttpRequestInfo request2;
11432 request2.method = "GET";
11433 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411434 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011435 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411436 TestCompletionCallback callback2;
11437 EXPECT_EQ(ERR_IO_PENDING,
11438 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411439 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411440
11441 EXPECT_EQ(OK, callback2.WaitForResult());
11442 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11443}
11444
[email protected]2d88e7d2012-07-19 17:55:1711445// Test that in the case where we have a SPDY session to a SPDY proxy
11446// that we do not pool other origins that resolve to the same IP when
11447// the certificate does not match the new origin.
11448// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211449TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711450 const std::string url1 = "http://www.google.com/";
11451 const std::string url2 = "https://mail.google.com/";
11452 const std::string ip_addr = "1.2.3.4";
11453
11454 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211455 scoped_ptr<SpdyHeaderBlock> headers(
11456 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311457 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211458 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711459
11460 MockWrite writes1[] = {
11461 CreateMockWrite(*req1, 0),
11462 };
11463
[email protected]23e482282013-06-14 16:08:0211464 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11465 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711466 MockRead reads1[] = {
11467 CreateMockRead(*resp1, 1),
11468 CreateMockRead(*body1, 2),
11469 MockRead(ASYNC, OK, 3) // EOF
11470 };
11471
11472 scoped_ptr<DeterministicSocketData> data1(
11473 new DeterministicSocketData(reads1, arraysize(reads1),
11474 writes1, arraysize(writes1)));
11475 IPAddressNumber ip;
11476 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11477 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11478 MockConnect connect_data1(ASYNC, OK, peer_addr);
11479 data1->set_connect_data(connect_data1);
11480
11481 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611482 scoped_ptr<SpdyFrame> req2(
11483 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711484
11485 MockWrite writes2[] = {
11486 CreateMockWrite(*req2, 0),
11487 };
11488
[email protected]23e482282013-06-14 16:08:0211489 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11490 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711491 MockRead reads2[] = {
11492 CreateMockRead(*resp2, 1),
11493 CreateMockRead(*body2, 2),
11494 MockRead(ASYNC, OK, 3) // EOF
11495 };
11496
11497 scoped_ptr<DeterministicSocketData> data2(
11498 new DeterministicSocketData(reads2, arraysize(reads2),
11499 writes2, arraysize(writes2)));
11500 MockConnect connect_data2(ASYNC, OK);
11501 data2->set_connect_data(connect_data2);
11502
11503 // Set up a proxy config that sends HTTP requests to a proxy, and
11504 // all others direct.
11505 ProxyConfig proxy_config;
11506 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11507 CapturingProxyResolver* capturing_proxy_resolver =
11508 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711509 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711510 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11511 NULL));
11512
11513 // Load a valid cert. Note, that this does not need to
11514 // be valid for proxy because the MockSSLClientSocket does
11515 // not actually verify it. But SpdySession will use this
11516 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511517 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711518 scoped_refptr<X509Certificate> server_cert(
11519 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11520 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11521
11522 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211523 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711524 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711525 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11526 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11527 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711528
11529 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211530 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711531 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11532 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11533 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711534
[email protected]bb88e1d32013-05-03 23:11:0711535 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11536 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11537 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711538
11539 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711540 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711541
11542 // Start the first transaction to set up the SpdySession
11543 HttpRequestInfo request1;
11544 request1.method = "GET";
11545 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711546 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011547 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711548 TestCompletionCallback callback1;
11549 ASSERT_EQ(ERR_IO_PENDING,
11550 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11551 data1->RunFor(3);
11552
11553 ASSERT_TRUE(callback1.have_result());
11554 EXPECT_EQ(OK, callback1.WaitForResult());
11555 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11556
11557 // Now, start the HTTP request
11558 HttpRequestInfo request2;
11559 request2.method = "GET";
11560 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711561 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011562 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711563 TestCompletionCallback callback2;
11564 EXPECT_EQ(ERR_IO_PENDING,
11565 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411566 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711567 data2->RunFor(3);
11568
11569 ASSERT_TRUE(callback2.have_result());
11570 EXPECT_EQ(OK, callback2.WaitForResult());
11571 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11572}
11573
[email protected]85f97342013-04-17 06:12:2411574// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11575// error) in SPDY session, removes the socket from pool and closes the SPDY
11576// session. Verify that new url's from the same HttpNetworkSession (and a new
11577// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211578TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411579 const std::string https_url = "https://www.google.com/";
11580
11581 MockRead reads1[] = {
11582 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11583 };
11584
11585 scoped_ptr<DeterministicSocketData> data1(
11586 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11587 data1->SetStop(1);
11588
[email protected]cdf8f7e72013-05-23 10:56:4611589 scoped_ptr<SpdyFrame> req2(
11590 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411591 MockWrite writes2[] = {
11592 CreateMockWrite(*req2, 0),
11593 };
11594
[email protected]23e482282013-06-14 16:08:0211595 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11596 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411597 MockRead reads2[] = {
11598 CreateMockRead(*resp2, 1),
11599 CreateMockRead(*body2, 2),
11600 MockRead(ASYNC, OK, 3) // EOF
11601 };
11602
11603 scoped_ptr<DeterministicSocketData> data2(
11604 new DeterministicSocketData(reads2, arraysize(reads2),
11605 writes2, arraysize(writes2)));
11606
[email protected]85f97342013-04-17 06:12:2411607 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211608 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711609 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11610 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11611 data1.get());
[email protected]85f97342013-04-17 06:12:2411612
11613 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211614 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711615 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11616 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11617 data2.get());
[email protected]85f97342013-04-17 06:12:2411618
11619 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711620 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411621
11622 // Start the first transaction to set up the SpdySession and verify that
11623 // connection was closed.
11624 HttpRequestInfo request1;
11625 request1.method = "GET";
11626 request1.url = GURL(https_url);
11627 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011628 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411629 TestCompletionCallback callback1;
11630 EXPECT_EQ(ERR_IO_PENDING,
11631 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411632 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411633 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11634
11635 // Now, start the second request and make sure it succeeds.
11636 HttpRequestInfo request2;
11637 request2.method = "GET";
11638 request2.url = GURL(https_url);
11639 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011640 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411641 TestCompletionCallback callback2;
11642 EXPECT_EQ(ERR_IO_PENDING,
11643 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411644 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411645 data2->RunFor(3);
11646
11647 ASSERT_TRUE(callback2.have_result());
11648 EXPECT_EQ(OK, callback2.WaitForResult());
11649 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11650}
11651
[email protected]23e482282013-06-14 16:08:0211652TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311653 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11654 ClientSocketPoolManager::set_max_sockets_per_group(
11655 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11656 ClientSocketPoolManager::set_max_sockets_per_pool(
11657 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11658
11659 // Use two different hosts with different IPs so they don't get pooled.
11660 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11661 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11662 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11663
11664 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211665 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311666 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211667 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311668 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11670
[email protected]cdf8f7e72013-05-23 10:56:4611671 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311672 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11673 MockWrite spdy1_writes[] = {
11674 CreateMockWrite(*host1_req, 1),
11675 };
[email protected]23e482282013-06-14 16:08:0211676 scoped_ptr<SpdyFrame> host1_resp(
11677 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11678 scoped_ptr<SpdyFrame> host1_resp_body(
11679 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311680 MockRead spdy1_reads[] = {
11681 CreateMockRead(*host1_resp, 2),
11682 CreateMockRead(*host1_resp_body, 3),
11683 MockRead(ASYNC, ERR_IO_PENDING, 4),
11684 };
11685
11686 scoped_ptr<OrderedSocketData> spdy1_data(
11687 new OrderedSocketData(
11688 spdy1_reads, arraysize(spdy1_reads),
11689 spdy1_writes, arraysize(spdy1_writes)));
11690 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11691
[email protected]cdf8f7e72013-05-23 10:56:4611692 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311693 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11694 MockWrite spdy2_writes[] = {
11695 CreateMockWrite(*host2_req, 1),
11696 };
[email protected]23e482282013-06-14 16:08:0211697 scoped_ptr<SpdyFrame> host2_resp(
11698 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11699 scoped_ptr<SpdyFrame> host2_resp_body(
11700 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311701 MockRead spdy2_reads[] = {
11702 CreateMockRead(*host2_resp, 2),
11703 CreateMockRead(*host2_resp_body, 3),
11704 MockRead(ASYNC, ERR_IO_PENDING, 4),
11705 };
11706
11707 scoped_ptr<OrderedSocketData> spdy2_data(
11708 new OrderedSocketData(
11709 spdy2_reads, arraysize(spdy2_reads),
11710 spdy2_writes, arraysize(spdy2_writes)));
11711 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11712
11713 MockWrite http_write[] = {
11714 MockWrite("GET / HTTP/1.1\r\n"
11715 "Host: www.a.com\r\n"
11716 "Connection: keep-alive\r\n\r\n"),
11717 };
11718
11719 MockRead http_read[] = {
11720 MockRead("HTTP/1.1 200 OK\r\n"),
11721 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11722 MockRead("Content-Length: 6\r\n\r\n"),
11723 MockRead("hello!"),
11724 };
11725 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11726 http_write, arraysize(http_write));
11727 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11728
11729 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011730 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5311731 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311732 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611733 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311734
11735 TestCompletionCallback callback;
11736 HttpRequestInfo request1;
11737 request1.method = "GET";
11738 request1.url = GURL("https://www.a.com/");
11739 request1.load_flags = 0;
11740 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011741 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311742
11743 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11744 EXPECT_EQ(ERR_IO_PENDING, rv);
11745 EXPECT_EQ(OK, callback.WaitForResult());
11746
11747 const HttpResponseInfo* response = trans->GetResponseInfo();
11748 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011749 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311750 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11751 EXPECT_TRUE(response->was_fetched_via_spdy);
11752 EXPECT_TRUE(response->was_npn_negotiated);
11753
11754 std::string response_data;
11755 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11756 EXPECT_EQ("hello!", response_data);
11757 trans.reset();
11758 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611759 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311760
11761 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011762 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5311763 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311764 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611765 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311766 HttpRequestInfo request2;
11767 request2.method = "GET";
11768 request2.url = GURL("https://www.b.com/");
11769 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011770 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311771
11772 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11773 EXPECT_EQ(ERR_IO_PENDING, rv);
11774 EXPECT_EQ(OK, callback.WaitForResult());
11775
11776 response = trans->GetResponseInfo();
11777 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011778 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311779 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11780 EXPECT_TRUE(response->was_fetched_via_spdy);
11781 EXPECT_TRUE(response->was_npn_negotiated);
11782 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11783 EXPECT_EQ("hello!", response_data);
11784 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611785 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311786 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611787 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311788
11789 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011790 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5311791 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311792 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611793 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311794 HttpRequestInfo request3;
11795 request3.method = "GET";
11796 request3.url = GURL("http://www.a.com/");
11797 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011798 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311799
11800 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11801 EXPECT_EQ(ERR_IO_PENDING, rv);
11802 EXPECT_EQ(OK, callback.WaitForResult());
11803
11804 response = trans->GetResponseInfo();
11805 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011806 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311807 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11808 EXPECT_FALSE(response->was_fetched_via_spdy);
11809 EXPECT_FALSE(response->was_npn_negotiated);
11810 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11811 EXPECT_EQ("hello!", response_data);
11812 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611813 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311814 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611815 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311816}
11817
[email protected]79e1fd62013-06-20 06:50:0411818TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11819 HttpRequestInfo request;
11820 request.method = "GET";
11821 request.url = GURL("http://www.google.com/");
11822 request.load_flags = 0;
11823
[email protected]3fe8d2f82013-10-17 08:56:0711824 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411825 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711826 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411827
11828 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11829 StaticSocketDataProvider data;
11830 data.set_connect_data(mock_connect);
11831 session_deps_.socket_factory->AddSocketDataProvider(&data);
11832
11833 TestCompletionCallback callback;
11834
11835 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11836 EXPECT_EQ(ERR_IO_PENDING, rv);
11837
11838 rv = callback.WaitForResult();
11839 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11840
11841 EXPECT_EQ(NULL, trans->GetResponseInfo());
11842
11843 // We don't care whether this succeeds or fails, but it shouldn't crash.
11844 HttpRequestHeaders request_headers;
11845 trans->GetFullRequestHeaders(&request_headers);
11846}
11847
11848TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11849 HttpRequestInfo request;
11850 request.method = "GET";
11851 request.url = GURL("http://www.google.com/");
11852 request.load_flags = 0;
11853
[email protected]3fe8d2f82013-10-17 08:56:0711854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411855 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411857
11858 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11859 StaticSocketDataProvider data;
11860 data.set_connect_data(mock_connect);
11861 session_deps_.socket_factory->AddSocketDataProvider(&data);
11862
11863 TestCompletionCallback callback;
11864
11865 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11866 EXPECT_EQ(ERR_IO_PENDING, rv);
11867
11868 rv = callback.WaitForResult();
11869 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11870
11871 EXPECT_EQ(NULL, trans->GetResponseInfo());
11872
11873 // We don't care whether this succeeds or fails, but it shouldn't crash.
11874 HttpRequestHeaders request_headers;
11875 trans->GetFullRequestHeaders(&request_headers);
11876}
11877
11878TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11879 HttpRequestInfo request;
11880 request.method = "GET";
11881 request.url = GURL("http://www.google.com/");
11882 request.load_flags = 0;
11883
[email protected]3fe8d2f82013-10-17 08:56:0711884 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411885 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411887
11888 MockWrite data_writes[] = {
11889 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11890 };
11891 MockRead data_reads[] = {
11892 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11893 };
11894
11895 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11896 data_writes, arraysize(data_writes));
11897 session_deps_.socket_factory->AddSocketDataProvider(&data);
11898
11899 TestCompletionCallback callback;
11900
11901 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11902 EXPECT_EQ(ERR_IO_PENDING, rv);
11903
11904 rv = callback.WaitForResult();
11905 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11906
11907 EXPECT_EQ(NULL, trans->GetResponseInfo());
11908
11909 HttpRequestHeaders request_headers;
11910 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11911 EXPECT_TRUE(request_headers.HasHeader("Host"));
11912}
11913
11914TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11915 HttpRequestInfo request;
11916 request.method = "GET";
11917 request.url = GURL("http://www.google.com/");
11918 request.load_flags = 0;
11919
[email protected]3fe8d2f82013-10-17 08:56:0711920 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411921 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411923
11924 MockWrite data_writes[] = {
11925 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11926 };
11927 MockRead data_reads[] = {
11928 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11929 };
11930
11931 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11932 data_writes, arraysize(data_writes));
11933 session_deps_.socket_factory->AddSocketDataProvider(&data);
11934
11935 TestCompletionCallback callback;
11936
11937 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11938 EXPECT_EQ(ERR_IO_PENDING, rv);
11939
11940 rv = callback.WaitForResult();
11941 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11942
11943 EXPECT_EQ(NULL, trans->GetResponseInfo());
11944
11945 HttpRequestHeaders request_headers;
11946 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11947 EXPECT_TRUE(request_headers.HasHeader("Host"));
11948}
11949
11950TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
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 MockWrite data_writes[] = {
11961 MockWrite("GET / HTTP/1.1\r\n"
11962 "Host: www.google.com\r\n"
11963 "Connection: keep-alive\r\n\r\n"),
11964 };
11965 MockRead data_reads[] = {
11966 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11967 };
11968
11969 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11970 data_writes, arraysize(data_writes));
11971 session_deps_.socket_factory->AddSocketDataProvider(&data);
11972
11973 TestCompletionCallback callback;
11974
11975 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11976 EXPECT_EQ(ERR_IO_PENDING, rv);
11977
11978 rv = callback.WaitForResult();
11979 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11980
11981 EXPECT_EQ(NULL, trans->GetResponseInfo());
11982
11983 HttpRequestHeaders request_headers;
11984 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11985 EXPECT_TRUE(request_headers.HasHeader("Host"));
11986}
11987
11988TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11989 HttpRequestInfo request;
11990 request.method = "GET";
11991 request.url = GURL("http://www.google.com/");
11992 request.load_flags = 0;
11993
[email protected]3fe8d2f82013-10-17 08:56:0711994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411995 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711996 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411997
11998 MockWrite data_writes[] = {
11999 MockWrite("GET / HTTP/1.1\r\n"
12000 "Host: www.google.com\r\n"
12001 "Connection: keep-alive\r\n\r\n"),
12002 };
12003 MockRead data_reads[] = {
12004 MockRead(ASYNC, ERR_CONNECTION_RESET),
12005 };
12006
12007 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12008 data_writes, arraysize(data_writes));
12009 session_deps_.socket_factory->AddSocketDataProvider(&data);
12010
12011 TestCompletionCallback callback;
12012
12013 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12014 EXPECT_EQ(ERR_IO_PENDING, rv);
12015
12016 rv = callback.WaitForResult();
12017 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12018
12019 EXPECT_EQ(NULL, trans->GetResponseInfo());
12020
12021 HttpRequestHeaders request_headers;
12022 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12023 EXPECT_TRUE(request_headers.HasHeader("Host"));
12024}
12025
12026TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12027 HttpRequestInfo request;
12028 request.method = "GET";
12029 request.url = GURL("http://www.google.com/");
12030 request.load_flags = 0;
12031 request.extra_headers.SetHeader("X-Foo", "bar");
12032
[email protected]3fe8d2f82013-10-17 08:56:0712033 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412034 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0712035 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0412036
12037 MockWrite data_writes[] = {
12038 MockWrite("GET / HTTP/1.1\r\n"
12039 "Host: www.google.com\r\n"
12040 "Connection: keep-alive\r\n"
12041 "X-Foo: bar\r\n\r\n"),
12042 };
12043 MockRead data_reads[] = {
12044 MockRead("HTTP/1.1 200 OK\r\n"
12045 "Content-Length: 5\r\n\r\n"
12046 "hello"),
12047 MockRead(ASYNC, ERR_UNEXPECTED),
12048 };
12049
12050 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12051 data_writes, arraysize(data_writes));
12052 session_deps_.socket_factory->AddSocketDataProvider(&data);
12053
12054 TestCompletionCallback callback;
12055
12056 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12057 EXPECT_EQ(ERR_IO_PENDING, rv);
12058
12059 rv = callback.WaitForResult();
12060 EXPECT_EQ(OK, rv);
12061
12062 HttpRequestHeaders request_headers;
12063 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12064 std::string foo;
12065 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12066 EXPECT_EQ("bar", foo);
12067}
12068
[email protected]bf828982013-08-14 18:01:4712069namespace {
12070
[email protected]e86839fd2013-08-14 18:29:0312071// Fake HttpStreamBase that simply records calls to SetPriority().
12072class FakeStream : public HttpStreamBase,
12073 public base::SupportsWeakPtr<FakeStream> {
12074 public:
12075 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
12076 virtual ~FakeStream() {}
12077
12078 RequestPriority priority() const { return priority_; }
12079
12080 virtual int InitializeStream(const HttpRequestInfo* request_info,
12081 RequestPriority priority,
12082 const BoundNetLog& net_log,
12083 const CompletionCallback& callback) OVERRIDE {
12084 return ERR_IO_PENDING;
12085 }
12086
12087 virtual int SendRequest(const HttpRequestHeaders& request_headers,
12088 HttpResponseInfo* response,
12089 const CompletionCallback& callback) OVERRIDE {
12090 ADD_FAILURE();
12091 return ERR_UNEXPECTED;
12092 }
12093
12094 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
12095 ADD_FAILURE();
12096 return ERR_UNEXPECTED;
12097 }
12098
12099 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
12100 ADD_FAILURE();
12101 return NULL;
12102 }
12103
12104 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
12105 const CompletionCallback& callback) OVERRIDE {
12106 ADD_FAILURE();
12107 return ERR_UNEXPECTED;
12108 }
12109
12110 virtual void Close(bool not_reusable) OVERRIDE {}
12111
12112 virtual bool IsResponseBodyComplete() const OVERRIDE {
12113 ADD_FAILURE();
12114 return false;
12115 }
12116
12117 virtual bool CanFindEndOfResponse() const OVERRIDE {
12118 return false;
12119 }
12120
12121 virtual bool IsConnectionReused() const OVERRIDE {
12122 ADD_FAILURE();
12123 return false;
12124 }
12125
12126 virtual void SetConnectionReused() OVERRIDE {
12127 ADD_FAILURE();
12128 }
12129
12130 virtual bool IsConnectionReusable() const OVERRIDE {
12131 ADD_FAILURE();
12132 return false;
12133 }
12134
[email protected]bc92bc972013-12-13 08:32:5912135 virtual int64 GetTotalReceivedBytes() const OVERRIDE {
12136 ADD_FAILURE();
12137 return 0;
12138 }
12139
[email protected]e86839fd2013-08-14 18:29:0312140 virtual bool GetLoadTimingInfo(
12141 LoadTimingInfo* load_timing_info) const OVERRIDE {
12142 ADD_FAILURE();
12143 return false;
12144 }
12145
12146 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
12147 ADD_FAILURE();
12148 }
12149
12150 virtual void GetSSLCertRequestInfo(
12151 SSLCertRequestInfo* cert_request_info) OVERRIDE {
12152 ADD_FAILURE();
12153 }
12154
12155 virtual bool IsSpdyHttpStream() const OVERRIDE {
12156 ADD_FAILURE();
12157 return false;
12158 }
12159
12160 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
12161 ADD_FAILURE();
12162 }
12163
12164 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12165 priority_ = priority;
12166 }
12167
12168 private:
12169 RequestPriority priority_;
12170
12171 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12172};
12173
12174// Fake HttpStreamRequest that simply records calls to SetPriority()
12175// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712176class FakeStreamRequest : public HttpStreamRequest,
12177 public base::SupportsWeakPtr<FakeStreamRequest> {
12178 public:
[email protected]e86839fd2013-08-14 18:29:0312179 FakeStreamRequest(RequestPriority priority,
12180 HttpStreamRequest::Delegate* delegate)
12181 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412182 delegate_(delegate),
12183 websocket_stream_create_helper_(NULL) {}
12184
12185 FakeStreamRequest(RequestPriority priority,
12186 HttpStreamRequest::Delegate* delegate,
12187 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12188 : priority_(priority),
12189 delegate_(delegate),
12190 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312191
[email protected]bf828982013-08-14 18:01:4712192 virtual ~FakeStreamRequest() {}
12193
12194 RequestPriority priority() const { return priority_; }
12195
[email protected]831e4a32013-11-14 02:14:4412196 const WebSocketHandshakeStreamBase::CreateHelper*
12197 websocket_stream_create_helper() const {
12198 return websocket_stream_create_helper_;
12199 }
12200
[email protected]e86839fd2013-08-14 18:29:0312201 // Create a new FakeStream and pass it to the request's
12202 // delegate. Returns a weak pointer to the FakeStream.
12203 base::WeakPtr<FakeStream> FinishStreamRequest() {
12204 FakeStream* fake_stream = new FakeStream(priority_);
12205 // Do this before calling OnStreamReady() as OnStreamReady() may
12206 // immediately delete |fake_stream|.
12207 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12208 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12209 return weak_stream;
12210 }
12211
[email protected]bf828982013-08-14 18:01:4712212 virtual int RestartTunnelWithProxyAuth(
12213 const AuthCredentials& credentials) OVERRIDE {
12214 ADD_FAILURE();
12215 return ERR_UNEXPECTED;
12216 }
12217
12218 virtual LoadState GetLoadState() const OVERRIDE {
12219 ADD_FAILURE();
12220 return LoadState();
12221 }
12222
12223 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12224 priority_ = priority;
12225 }
12226
12227 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712228 return false;
12229 }
12230
12231 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712232 return kProtoUnknown;
12233 }
12234
12235 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712236 return false;
12237 }
12238
12239 private:
12240 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312241 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412242 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712243
12244 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12245};
12246
12247// Fake HttpStreamFactory that vends FakeStreamRequests.
12248class FakeStreamFactory : public HttpStreamFactory {
12249 public:
12250 FakeStreamFactory() {}
12251 virtual ~FakeStreamFactory() {}
12252
12253 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12254 // RequestStream() (which may be NULL if it was destroyed already).
12255 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12256 return last_stream_request_;
12257 }
12258
12259 virtual HttpStreamRequest* RequestStream(
12260 const HttpRequestInfo& info,
12261 RequestPriority priority,
12262 const SSLConfig& server_ssl_config,
12263 const SSLConfig& proxy_ssl_config,
12264 HttpStreamRequest::Delegate* delegate,
12265 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0312266 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712267 last_stream_request_ = fake_request->AsWeakPtr();
12268 return fake_request;
12269 }
12270
[email protected]a9cf2b92013-10-30 12:08:4912271 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712272 const HttpRequestInfo& info,
12273 RequestPriority priority,
12274 const SSLConfig& server_ssl_config,
12275 const SSLConfig& proxy_ssl_config,
12276 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612277 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4712278 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4412279 FakeStreamRequest* fake_request =
12280 new FakeStreamRequest(priority, delegate, create_helper);
12281 last_stream_request_ = fake_request->AsWeakPtr();
12282 return fake_request;
[email protected]bf828982013-08-14 18:01:4712283 }
12284
12285 virtual void PreconnectStreams(int num_streams,
12286 const HttpRequestInfo& info,
12287 RequestPriority priority,
12288 const SSLConfig& server_ssl_config,
12289 const SSLConfig& proxy_ssl_config) OVERRIDE {
12290 ADD_FAILURE();
12291 }
12292
12293 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
12294 ADD_FAILURE();
12295 return NULL;
12296 }
12297
12298 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12299 ADD_FAILURE();
12300 return NULL;
12301 }
12302
12303 private:
12304 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12305
12306 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12307};
12308
[email protected]831e4a32013-11-14 02:14:4412309// TODO(yhirano): Split this class out into a net/websockets file, if it is
12310// worth doing.
12311class FakeWebSocketStreamCreateHelper :
12312 public WebSocketHandshakeStreamBase::CreateHelper {
12313 public:
12314 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112315 scoped_ptr<ClientSocketHandle> connection,
[email protected]831e4a32013-11-14 02:14:4412316 bool using_proxy) OVERRIDE {
12317 NOTREACHED();
12318 return NULL;
12319 }
12320
12321 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12322 const base::WeakPtr<SpdySession>& session,
12323 bool use_relative_url) OVERRIDE {
12324 NOTREACHED();
12325 return NULL;
12326 };
12327
12328 virtual ~FakeWebSocketStreamCreateHelper() {}
12329
12330 virtual scoped_ptr<WebSocketStream> Upgrade() {
12331 NOTREACHED();
12332 return scoped_ptr<WebSocketStream>();
12333 }
12334};
12335
[email protected]bf828982013-08-14 18:01:4712336} // namespace
12337
12338// Make sure that HttpNetworkTransaction passes on its priority to its
12339// stream request on start.
12340TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12342 HttpNetworkSessionPeer peer(session);
12343 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412344 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712345
12346 HttpNetworkTransaction trans(LOW, session);
12347
12348 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12349
12350 HttpRequestInfo request;
12351 TestCompletionCallback callback;
12352 EXPECT_EQ(ERR_IO_PENDING,
12353 trans.Start(&request, callback.callback(), BoundNetLog()));
12354
12355 base::WeakPtr<FakeStreamRequest> fake_request =
12356 fake_factory->last_stream_request();
12357 ASSERT_TRUE(fake_request != NULL);
12358 EXPECT_EQ(LOW, fake_request->priority());
12359}
12360
12361// Make sure that HttpNetworkTransaction passes on its priority
12362// updates to its stream request.
12363TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12364 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12365 HttpNetworkSessionPeer peer(session);
12366 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412367 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712368
12369 HttpNetworkTransaction trans(LOW, session);
12370
12371 HttpRequestInfo request;
12372 TestCompletionCallback callback;
12373 EXPECT_EQ(ERR_IO_PENDING,
12374 trans.Start(&request, callback.callback(), BoundNetLog()));
12375
12376 base::WeakPtr<FakeStreamRequest> fake_request =
12377 fake_factory->last_stream_request();
12378 ASSERT_TRUE(fake_request != NULL);
12379 EXPECT_EQ(LOW, fake_request->priority());
12380
12381 trans.SetPriority(LOWEST);
12382 ASSERT_TRUE(fake_request != NULL);
12383 EXPECT_EQ(LOWEST, fake_request->priority());
12384}
12385
[email protected]e86839fd2013-08-14 18:29:0312386// Make sure that HttpNetworkTransaction passes on its priority
12387// updates to its stream.
12388TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12389 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12390 HttpNetworkSessionPeer peer(session);
12391 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412392 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312393
12394 HttpNetworkTransaction trans(LOW, session);
12395
12396 HttpRequestInfo request;
12397 TestCompletionCallback callback;
12398 EXPECT_EQ(ERR_IO_PENDING,
12399 trans.Start(&request, callback.callback(), BoundNetLog()));
12400
12401 base::WeakPtr<FakeStreamRequest> fake_request =
12402 fake_factory->last_stream_request();
12403 ASSERT_TRUE(fake_request != NULL);
12404 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12405 ASSERT_TRUE(fake_stream != NULL);
12406 EXPECT_EQ(LOW, fake_stream->priority());
12407
12408 trans.SetPriority(LOWEST);
12409 EXPECT_EQ(LOWEST, fake_stream->priority());
12410}
12411
[email protected]831e4a32013-11-14 02:14:4412412TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12413 // The same logic needs to be tested for both ws: and wss: schemes, but this
12414 // test is already parameterised on NextProto, so it uses a loop to verify
12415 // that the different schemes work.
12416 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12417 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12418 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12419 HttpNetworkSessionPeer peer(session);
12420 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12421 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312422 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412423 scoped_ptr<HttpStreamFactory>(fake_factory));
12424
12425 HttpNetworkTransaction trans(LOW, session);
12426 trans.SetWebSocketHandshakeStreamCreateHelper(
12427 &websocket_stream_create_helper);
12428
12429 HttpRequestInfo request;
12430 TestCompletionCallback callback;
12431 request.method = "GET";
12432 request.url = GURL(test_cases[i]);
12433
12434 EXPECT_EQ(ERR_IO_PENDING,
12435 trans.Start(&request, callback.callback(), BoundNetLog()));
12436
12437 base::WeakPtr<FakeStreamRequest> fake_request =
12438 fake_factory->last_stream_request();
12439 ASSERT_TRUE(fake_request != NULL);
12440 EXPECT_EQ(&websocket_stream_create_helper,
12441 fake_request->websocket_stream_create_helper());
12442 }
12443}
12444
[email protected]043b68c82013-08-22 23:41:5212445// Tests that when a used socket is returned to the SSL socket pool, it's closed
12446// if the transport socket pool is stalled on the global socket limit.
12447TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12448 ClientSocketPoolManager::set_max_sockets_per_group(
12449 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12450 ClientSocketPoolManager::set_max_sockets_per_pool(
12451 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12452
12453 // Set up SSL request.
12454
12455 HttpRequestInfo ssl_request;
12456 ssl_request.method = "GET";
12457 ssl_request.url = GURL("https://www.google.com/");
12458
12459 MockWrite ssl_writes[] = {
12460 MockWrite("GET / HTTP/1.1\r\n"
12461 "Host: www.google.com\r\n"
12462 "Connection: keep-alive\r\n\r\n"),
12463 };
12464 MockRead ssl_reads[] = {
12465 MockRead("HTTP/1.1 200 OK\r\n"),
12466 MockRead("Content-Length: 11\r\n\r\n"),
12467 MockRead("hello world"),
12468 MockRead(SYNCHRONOUS, OK),
12469 };
12470 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12471 ssl_writes, arraysize(ssl_writes));
12472 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12473
12474 SSLSocketDataProvider ssl(ASYNC, OK);
12475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12476
12477 // Set up HTTP request.
12478
12479 HttpRequestInfo http_request;
12480 http_request.method = "GET";
12481 http_request.url = GURL("http://www.google.com/");
12482
12483 MockWrite http_writes[] = {
12484 MockWrite("GET / HTTP/1.1\r\n"
12485 "Host: www.google.com\r\n"
12486 "Connection: keep-alive\r\n\r\n"),
12487 };
12488 MockRead http_reads[] = {
12489 MockRead("HTTP/1.1 200 OK\r\n"),
12490 MockRead("Content-Length: 7\r\n\r\n"),
12491 MockRead("falafel"),
12492 MockRead(SYNCHRONOUS, OK),
12493 };
12494 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12495 http_writes, arraysize(http_writes));
12496 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12497
12498 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12499
12500 // Start the SSL request.
12501 TestCompletionCallback ssl_callback;
12502 scoped_ptr<HttpTransaction> ssl_trans(
12503 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12504 ASSERT_EQ(ERR_IO_PENDING,
12505 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12506 BoundNetLog()));
12507
12508 // Start the HTTP request. Pool should stall.
12509 TestCompletionCallback http_callback;
12510 scoped_ptr<HttpTransaction> http_trans(
12511 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12512 ASSERT_EQ(ERR_IO_PENDING,
12513 http_trans->Start(&http_request, http_callback.callback(),
12514 BoundNetLog()));
12515 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12516
12517 // Wait for response from SSL request.
12518 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12519 std::string response_data;
12520 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12521 EXPECT_EQ("hello world", response_data);
12522
12523 // The SSL socket should automatically be closed, so the HTTP request can
12524 // start.
12525 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12526 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12527
12528 // The HTTP request can now complete.
12529 ASSERT_EQ(OK, http_callback.WaitForResult());
12530 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12531 EXPECT_EQ("falafel", response_data);
12532
12533 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12534}
12535
12536// Tests that when a SSL connection is established but there's no corresponding
12537// request that needs it, the new socket is closed if the transport socket pool
12538// is stalled on the global socket limit.
12539TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12540 ClientSocketPoolManager::set_max_sockets_per_group(
12541 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12542 ClientSocketPoolManager::set_max_sockets_per_pool(
12543 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12544
12545 // Set up an ssl request.
12546
12547 HttpRequestInfo ssl_request;
12548 ssl_request.method = "GET";
12549 ssl_request.url = GURL("https://www.foopy.com/");
12550
12551 // No data will be sent on the SSL socket.
12552 StaticSocketDataProvider ssl_data;
12553 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12554
12555 SSLSocketDataProvider ssl(ASYNC, OK);
12556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12557
12558 // Set up HTTP request.
12559
12560 HttpRequestInfo http_request;
12561 http_request.method = "GET";
12562 http_request.url = GURL("http://www.google.com/");
12563
12564 MockWrite http_writes[] = {
12565 MockWrite("GET / HTTP/1.1\r\n"
12566 "Host: www.google.com\r\n"
12567 "Connection: keep-alive\r\n\r\n"),
12568 };
12569 MockRead http_reads[] = {
12570 MockRead("HTTP/1.1 200 OK\r\n"),
12571 MockRead("Content-Length: 7\r\n\r\n"),
12572 MockRead("falafel"),
12573 MockRead(SYNCHRONOUS, OK),
12574 };
12575 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12576 http_writes, arraysize(http_writes));
12577 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12578
12579 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12580
12581 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12582 // cancelled when a normal transaction is cancelled.
12583 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12584 net::SSLConfig ssl_config;
12585 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12586 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12587 ssl_config, ssl_config);
12588 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12589
12590 // Start the HTTP request. Pool should stall.
12591 TestCompletionCallback http_callback;
12592 scoped_ptr<HttpTransaction> http_trans(
12593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12594 ASSERT_EQ(ERR_IO_PENDING,
12595 http_trans->Start(&http_request, http_callback.callback(),
12596 BoundNetLog()));
12597 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12598
12599 // The SSL connection will automatically be closed once the connection is
12600 // established, to let the HTTP request start.
12601 ASSERT_EQ(OK, http_callback.WaitForResult());
12602 std::string response_data;
12603 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12604 EXPECT_EQ("falafel", response_data);
12605
12606 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12607}
12608
[email protected]89ceba9a2009-03-21 03:46:0612609} // namespace net