blob: 13cef372d5242c49b04980287eed0e5ec825c4da [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,
292 const MockRead* read_failure);
293
[email protected]5a60c8b2011-10-19 20:14:29294 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
295 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15296 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52297
[email protected]ff007e162009-05-23 09:13:15298 HttpRequestInfo request;
299 request.method = "GET";
300 request.url = GURL("http://www.google.com/");
301 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52302
[email protected]58e32bb2013-01-21 18:23:25303 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07304 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27306 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27308
[email protected]5a60c8b2011-10-19 20:14:29309 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07310 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29311 }
initial.commit586acc5fe2008-07-26 22:42:52312
[email protected]49639fa2011-12-20 23:22:41313 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52314
[email protected]c47c0372014-03-12 23:07:02315 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41316 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15317 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52318
[email protected]ff007e162009-05-23 09:13:15319 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25320
321 // Even in the failure cases that use this function, connections are always
322 // successfully established before the error.
323 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
324 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
325
[email protected]ff007e162009-05-23 09:13:15326 if (out.rv != OK)
327 return out;
328
329 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50330 // Can't use ASSERT_* inside helper functions like this, so
331 // return an error.
[email protected]90499482013-06-01 00:39:50332 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50333 out.rv = ERR_UNEXPECTED;
334 return out;
335 }
[email protected]ff007e162009-05-23 09:13:15336 out.status_line = response->headers->GetStatusLine();
337
[email protected]80a09a82012-11-16 17:40:06338 EXPECT_EQ("127.0.0.1", response->socket_address.host());
339 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19340
[email protected]ff007e162009-05-23 09:13:15341 rv = ReadTransaction(trans.get(), &out.response_data);
342 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40343
[email protected]f3da152d2012-06-02 01:00:57344 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40345 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39346 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40347 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12348 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39349 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40350 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39351 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
352 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15353
[email protected]f3da152d2012-06-02 01:00:57354 std::string line;
355 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
356 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
357
[email protected]79e1fd62013-06-20 06:50:04358 HttpRequestHeaders request_headers;
359 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
360 std::string value;
361 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
362 EXPECT_EQ("www.google.com", value);
363 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
364 EXPECT_EQ("keep-alive", value);
365
366 std::string response_headers;
367 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
368 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
369 response_headers);
[email protected]3deb9a52010-11-11 00:24:40370
[email protected]b8015c42013-12-24 15:18:19371 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47372 return out;
[email protected]ff007e162009-05-23 09:13:15373 }
initial.commit586acc5fe2008-07-26 22:42:52374
[email protected]5a60c8b2011-10-19 20:14:29375 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
376 size_t reads_count) {
377 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
378 StaticSocketDataProvider* data[] = { &reads };
379 return SimpleGetHelperForData(data, 1);
380 }
381
[email protected]b8015c42013-12-24 15:18:19382 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
383 int64 size = 0;
384 for (size_t i = 0; i < reads_count; ++i)
385 size += data_reads[i].data_len;
386 return size;
387 }
388
[email protected]ff007e162009-05-23 09:13:15389 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
390 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52391
[email protected]ff007e162009-05-23 09:13:15392 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07393
394 void BypassHostCacheOnRefreshHelper(int load_flags);
395
396 void CheckErrorIsPassedBack(int error, IoMode mode);
397
[email protected]4bd46222013-05-14 19:32:23398 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07399 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03400
401 // Original socket limits. Some tests set these. Safest to always restore
402 // them once each test has been run.
403 int old_max_group_sockets_;
404 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15405};
[email protected]231d5a32008-09-13 00:45:27406
[email protected]23e482282013-06-14 16:08:02407INSTANTIATE_TEST_CASE_P(
408 NextProto,
409 HttpNetworkTransactionTest,
[email protected]b05bcaa32013-10-06 05:26:02410 testing::Values(kProtoDeprecatedSPDY2,
411 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
[email protected]88a332622013-07-30 07:13:32412 kProtoHTTP2Draft04));
[email protected]23e482282013-06-14 16:08:02413
[email protected]448d4ca52012-03-04 04:12:23414namespace {
415
[email protected]1826a402014-01-08 15:40:48416class BeforeNetworkStartHandler {
417 public:
418 explicit BeforeNetworkStartHandler(bool defer)
419 : defer_on_before_network_start_(defer),
420 observed_before_network_start_(false) {}
421
422 void OnBeforeNetworkStart(bool* defer) {
423 *defer = defer_on_before_network_start_;
424 observed_before_network_start_ = true;
425 }
426
427 bool observed_before_network_start() const {
428 return observed_before_network_start_;
429 }
430
431 private:
432 const bool defer_on_before_network_start_;
433 bool observed_before_network_start_;
434
435 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
436};
437
[email protected]15a5ccf82008-10-23 19:57:43438// Fill |str| with a long header list that consumes >= |size| bytes.
439void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19440 const char* row =
441 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
442 const int sizeof_row = strlen(row);
443 const int num_rows = static_cast<int>(
444 ceil(static_cast<float>(size) / sizeof_row));
445 const int sizeof_data = num_rows * sizeof_row;
446 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43447 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51448
[email protected]4ddaf2502008-10-23 18:26:19449 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43450 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19451}
452
[email protected]385a4672009-03-11 22:21:29453// Alternative functions that eliminate randomness and dependency on the local
454// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20455void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29456 static const uint8 bytes[] = {
457 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
458 };
459 static size_t current_byte = 0;
460 for (size_t i = 0; i < n; ++i) {
461 output[i] = bytes[current_byte++];
462 current_byte %= arraysize(bytes);
463 }
464}
465
[email protected]fe2bc6a2009-03-23 16:52:20466void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29467 static const uint8 bytes[] = {
468 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
469 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
470 };
471 static size_t current_byte = 0;
472 for (size_t i = 0; i < n; ++i) {
473 output[i] = bytes[current_byte++];
474 current_byte %= arraysize(bytes);
475 }
476}
477
[email protected]fe2bc6a2009-03-23 16:52:20478std::string MockGetHostName() {
479 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29480}
481
[email protected]e60e47a2010-07-14 03:37:18482template<typename ParentPool>
483class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31484 public:
[email protected]9e1bdd32011-02-03 21:48:34485 CaptureGroupNameSocketPool(HostResolver* host_resolver,
486 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18487
[email protected]d80a4322009-08-14 07:07:49488 const std::string last_group_name_received() const {
489 return last_group_name_;
490 }
491
[email protected]684970b2009-08-14 04:54:46492 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49493 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31494 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31495 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41496 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53497 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31498 last_group_name_ = group_name;
499 return ERR_IO_PENDING;
500 }
[email protected]04e5be32009-06-26 20:00:31501 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21502 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31503 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44504 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19505 int id) {}
[email protected]04e5be32009-06-26 20:00:31506 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31507 virtual int IdleSocketCount() const {
508 return 0;
509 }
510 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
511 return 0;
512 }
513 virtual LoadState GetLoadState(const std::string& group_name,
514 const ClientSocketHandle* handle) const {
515 return LOAD_STATE_IDLE;
516 }
[email protected]a796bcec2010-03-22 17:17:26517 virtual base::TimeDelta ConnectionTimeout() const {
518 return base::TimeDelta();
519 }
[email protected]d80a4322009-08-14 07:07:49520
521 private:
[email protected]04e5be32009-06-26 20:00:31522 std::string last_group_name_;
523};
524
[email protected]ab739042011-04-07 15:22:28525typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
526CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13527typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
528CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06529typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11530CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18531typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
532CaptureGroupNameSSLSocketPool;
533
534template<typename ParentPool>
535CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34536 HostResolver* host_resolver,
537 CertVerifier* /* cert_verifier */)
538 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18539
540template<>
[email protected]2df19bb2010-08-25 20:13:46541CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34542 HostResolver* host_resolver,
543 CertVerifier* /* cert_verifier */)
544 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46545
[email protected]007b3f82013-04-09 08:46:45546template <>
[email protected]e60e47a2010-07-14 03:37:18547CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34548 HostResolver* host_resolver,
549 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45550 : SSLClientSocketPool(0,
551 0,
552 NULL,
553 host_resolver,
554 cert_verifier,
555 NULL,
556 NULL,
[email protected]284303b62013-11-28 15:11:54557 NULL,
[email protected]007b3f82013-04-09 08:46:45558 std::string(),
559 NULL,
560 NULL,
561 NULL,
562 NULL,
563 NULL,
564 NULL) {}
[email protected]2227c692010-05-04 15:36:11565
[email protected]231d5a32008-09-13 00:45:27566//-----------------------------------------------------------------------------
567
[email protected]79cb5c12011-09-12 13:12:04568// Helper functions for validating that AuthChallengeInfo's are correctly
569// configured for common cases.
570bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
571 if (!auth_challenge)
572 return false;
573 EXPECT_FALSE(auth_challenge->is_proxy);
574 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
575 EXPECT_EQ("MyRealm1", auth_challenge->realm);
576 EXPECT_EQ("basic", auth_challenge->scheme);
577 return true;
578}
579
580bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
581 if (!auth_challenge)
582 return false;
583 EXPECT_TRUE(auth_challenge->is_proxy);
584 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
585 EXPECT_EQ("MyRealm1", auth_challenge->realm);
586 EXPECT_EQ("basic", auth_challenge->scheme);
587 return true;
588}
589
590bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
591 if (!auth_challenge)
592 return false;
593 EXPECT_FALSE(auth_challenge->is_proxy);
594 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
595 EXPECT_EQ("digestive", auth_challenge->realm);
596 EXPECT_EQ("digest", auth_challenge->scheme);
597 return true;
598}
599
600bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
601 if (!auth_challenge)
602 return false;
603 EXPECT_FALSE(auth_challenge->is_proxy);
604 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
605 EXPECT_EQ(std::string(), auth_challenge->realm);
606 EXPECT_EQ("ntlm", auth_challenge->scheme);
607 return true;
608}
609
[email protected]448d4ca52012-03-04 04:12:23610} // namespace
611
[email protected]23e482282013-06-14 16:08:02612TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07613 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40614 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27616}
617
[email protected]23e482282013-06-14 16:08:02618TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27619 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35620 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
621 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06622 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27623 };
[email protected]31a2bfe2010-02-09 08:03:39624 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
625 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42626 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27627 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
628 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19629 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
630 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27631}
632
633// Response with no status line.
[email protected]23e482282013-06-14 16:08:02634TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27635 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35636 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06637 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27638 };
[email protected]31a2bfe2010-02-09 08:03:39639 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
640 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42641 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27642 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
643 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19644 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
645 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27646}
647
648// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02649TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27650 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35651 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06652 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27653 };
[email protected]31a2bfe2010-02-09 08:03:39654 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
655 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42656 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27657 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
658 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19659 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
660 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27661}
662
663// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02664TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27665 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35666 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06667 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27668 };
[email protected]31a2bfe2010-02-09 08:03:39669 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
670 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42671 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27672 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
673 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19674 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
675 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27676}
677
678// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02679TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27680 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35681 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06682 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27683 };
[email protected]31a2bfe2010-02-09 08:03:39684 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
685 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42686 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25687 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
688 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19689 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
690 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27691}
692
693// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02694TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27695 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35696 MockRead("\n"),
697 MockRead("\n"),
698 MockRead("Q"),
699 MockRead("J"),
700 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06701 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27702 };
[email protected]31a2bfe2010-02-09 08:03:39703 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
704 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42705 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27706 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
707 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19708 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
709 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27710}
711
712// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02713TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27714 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35715 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06716 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27717 };
[email protected]31a2bfe2010-02-09 08:03:39718 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
719 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42720 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27721 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
722 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19723 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
724 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52725}
726
[email protected]f9d44aa2008-09-23 23:57:17727// Simulate a 204 response, lacking a Content-Length header, sent over a
728// persistent connection. The response should still terminate since a 204
729// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02730TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19731 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17732 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35733 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19734 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06735 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17736 };
[email protected]31a2bfe2010-02-09 08:03:39737 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
738 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42739 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17740 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
741 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19742 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
743 int64 response_size = reads_size - strlen(junk);
744 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17745}
746
[email protected]0877e3d2009-10-17 22:29:57747// A simple request using chunked encoding with some extra data after.
748// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02749TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19750 std::string final_chunk = "0\r\n\r\n";
751 std::string extra_data = "HTTP/1.1 200 OK\r\n";
752 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57753 MockRead data_reads[] = {
754 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
755 MockRead("5\r\nHello\r\n"),
756 MockRead("1\r\n"),
757 MockRead(" \r\n"),
758 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19759 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06760 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57761 };
[email protected]31a2bfe2010-02-09 08:03:39762 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
763 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57764 EXPECT_EQ(OK, out.rv);
765 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
766 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19767 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
768 int64 response_size = reads_size - extra_data.size();
769 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57770}
771
[email protected]9fe44f52010-09-23 18:36:00772// Next tests deal with http://crbug.com/56344.
773
[email protected]23e482282013-06-14 16:08:02774TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00775 MultipleContentLengthHeadersNoTransferEncoding) {
776 MockRead data_reads[] = {
777 MockRead("HTTP/1.1 200 OK\r\n"),
778 MockRead("Content-Length: 10\r\n"),
779 MockRead("Content-Length: 5\r\n\r\n"),
780 };
781 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
782 arraysize(data_reads));
783 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
784}
785
[email protected]23e482282013-06-14 16:08:02786TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04787 DuplicateContentLengthHeadersNoTransferEncoding) {
788 MockRead data_reads[] = {
789 MockRead("HTTP/1.1 200 OK\r\n"),
790 MockRead("Content-Length: 5\r\n"),
791 MockRead("Content-Length: 5\r\n\r\n"),
792 MockRead("Hello"),
793 };
794 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
795 arraysize(data_reads));
796 EXPECT_EQ(OK, out.rv);
797 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
798 EXPECT_EQ("Hello", out.response_data);
799}
800
[email protected]23e482282013-06-14 16:08:02801TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04802 ComplexContentLengthHeadersNoTransferEncoding) {
803 // More than 2 dupes.
804 {
805 MockRead data_reads[] = {
806 MockRead("HTTP/1.1 200 OK\r\n"),
807 MockRead("Content-Length: 5\r\n"),
808 MockRead("Content-Length: 5\r\n"),
809 MockRead("Content-Length: 5\r\n\r\n"),
810 MockRead("Hello"),
811 };
812 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
813 arraysize(data_reads));
814 EXPECT_EQ(OK, out.rv);
815 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
816 EXPECT_EQ("Hello", out.response_data);
817 }
818 // HTTP/1.0
819 {
820 MockRead data_reads[] = {
821 MockRead("HTTP/1.0 200 OK\r\n"),
822 MockRead("Content-Length: 5\r\n"),
823 MockRead("Content-Length: 5\r\n"),
824 MockRead("Content-Length: 5\r\n\r\n"),
825 MockRead("Hello"),
826 };
827 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
828 arraysize(data_reads));
829 EXPECT_EQ(OK, out.rv);
830 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
831 EXPECT_EQ("Hello", out.response_data);
832 }
833 // 2 dupes and one mismatched.
834 {
835 MockRead data_reads[] = {
836 MockRead("HTTP/1.1 200 OK\r\n"),
837 MockRead("Content-Length: 10\r\n"),
838 MockRead("Content-Length: 10\r\n"),
839 MockRead("Content-Length: 5\r\n\r\n"),
840 };
841 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
842 arraysize(data_reads));
843 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
844 }
845}
846
[email protected]23e482282013-06-14 16:08:02847TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00848 MultipleContentLengthHeadersTransferEncoding) {
849 MockRead data_reads[] = {
850 MockRead("HTTP/1.1 200 OK\r\n"),
851 MockRead("Content-Length: 666\r\n"),
852 MockRead("Content-Length: 1337\r\n"),
853 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
854 MockRead("5\r\nHello\r\n"),
855 MockRead("1\r\n"),
856 MockRead(" \r\n"),
857 MockRead("5\r\nworld\r\n"),
858 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06859 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00860 };
861 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
862 arraysize(data_reads));
863 EXPECT_EQ(OK, out.rv);
864 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
865 EXPECT_EQ("Hello world", out.response_data);
866}
867
[email protected]1628fe92011-10-04 23:04:55868// Next tests deal with http://crbug.com/98895.
869
870// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02871TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55872 MockRead data_reads[] = {
873 MockRead("HTTP/1.1 200 OK\r\n"),
874 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
875 MockRead("Content-Length: 5\r\n\r\n"),
876 MockRead("Hello"),
877 };
878 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
879 arraysize(data_reads));
880 EXPECT_EQ(OK, out.rv);
881 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
882 EXPECT_EQ("Hello", out.response_data);
883}
884
[email protected]54a9c6e52012-03-21 20:10:59885// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02886TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59887 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55888 MockRead data_reads[] = {
889 MockRead("HTTP/1.1 200 OK\r\n"),
890 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
891 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
892 MockRead("Content-Length: 5\r\n\r\n"),
893 MockRead("Hello"),
894 };
895 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
896 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59897 EXPECT_EQ(OK, out.rv);
898 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
899 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55900}
901
902// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02903TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55904 MockRead data_reads[] = {
905 MockRead("HTTP/1.1 200 OK\r\n"),
906 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
907 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
908 MockRead("Content-Length: 5\r\n\r\n"),
909 MockRead("Hello"),
910 };
911 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
912 arraysize(data_reads));
913 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
914}
915
[email protected]54a9c6e52012-03-21 20:10:59916// Checks that two identical Location headers result in no error.
917// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02918TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55919 MockRead data_reads[] = {
920 MockRead("HTTP/1.1 302 Redirect\r\n"),
921 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59922 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55923 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06924 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55925 };
926
927 HttpRequestInfo request;
928 request.method = "GET";
929 request.url = GURL("http://redirect.com/");
930 request.load_flags = 0;
931
[email protected]3fe8d2f82013-10-17 08:56:07932 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55933 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07934 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55935
936 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07937 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55938
[email protected]49639fa2011-12-20 23:22:41939 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55940
[email protected]49639fa2011-12-20 23:22:41941 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55942 EXPECT_EQ(ERR_IO_PENDING, rv);
943
944 EXPECT_EQ(OK, callback.WaitForResult());
945
946 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50947 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55948 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
949 std::string url;
950 EXPECT_TRUE(response->headers->IsRedirect(&url));
951 EXPECT_EQ("http://good.com/", url);
952}
953
[email protected]1628fe92011-10-04 23:04:55954// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02955TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55956 MockRead data_reads[] = {
957 MockRead("HTTP/1.1 302 Redirect\r\n"),
958 MockRead("Location: http://good.com/\r\n"),
959 MockRead("Location: http://evil.com/\r\n"),
960 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06961 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55962 };
963 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
964 arraysize(data_reads));
965 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
966}
967
[email protected]ef0faf2e72009-03-05 23:27:23968// Do a request using the HEAD method. Verify that we don't try to read the
969// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02970TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42971 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23972 request.method = "HEAD";
973 request.url = GURL("http://www.google.com/");
974 request.load_flags = 0;
975
[email protected]3fe8d2f82013-10-17 08:56:07976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27977 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27979
[email protected]ef0faf2e72009-03-05 23:27:23980 MockWrite data_writes1[] = {
981 MockWrite("HEAD / HTTP/1.1\r\n"
982 "Host: www.google.com\r\n"
983 "Connection: keep-alive\r\n"
984 "Content-Length: 0\r\n\r\n"),
985 };
986 MockRead data_reads1[] = {
987 MockRead("HTTP/1.1 404 Not Found\r\n"),
988 MockRead("Server: Blah\r\n"),
989 MockRead("Content-Length: 1234\r\n\r\n"),
990
991 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06992 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23993 };
994
[email protected]31a2bfe2010-02-09 08:03:39995 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
996 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07997 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23998
[email protected]49639fa2011-12-20 23:22:41999 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231000
[email protected]49639fa2011-12-20 23:22:411001 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421002 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231003
1004 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421005 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231006
[email protected]1c773ea12009-04-28 19:58:421007 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501008 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231009
1010 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501011 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231012 EXPECT_EQ(1234, response->headers->GetContentLength());
1013 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1014
1015 std::string server_header;
1016 void* iter = NULL;
1017 bool has_server_header = response->headers->EnumerateHeader(
1018 &iter, "Server", &server_header);
1019 EXPECT_TRUE(has_server_header);
1020 EXPECT_EQ("Blah", server_header);
1021
1022 // Reading should give EOF right away, since there is no message body
1023 // (despite non-zero content-length).
1024 std::string response_data;
1025 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421026 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231027 EXPECT_EQ("", response_data);
1028}
1029
[email protected]23e482282013-06-14 16:08:021030TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071031 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521032
1033 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351034 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1035 MockRead("hello"),
1036 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1037 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061038 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521039 };
[email protected]31a2bfe2010-02-09 08:03:391040 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071041 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521042
[email protected]0b0bf032010-09-21 18:08:501043 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521044 "hello", "world"
1045 };
1046
1047 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421048 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521049 request.method = "GET";
1050 request.url = GURL("http://www.google.com/");
1051 request.load_flags = 0;
1052
[email protected]262eec82013-03-19 21:01:361053 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271055
[email protected]49639fa2011-12-20 23:22:411056 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521057
[email protected]49639fa2011-12-20 23:22:411058 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421059 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521060
1061 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421062 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521063
[email protected]1c773ea12009-04-28 19:58:421064 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501065 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521066
[email protected]90499482013-06-01 00:39:501067 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251068 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521069
1070 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571071 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421072 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251073 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521074 }
1075}
1076
[email protected]23e482282013-06-14 16:08:021077TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061078 ScopedVector<UploadElementReader> element_readers;
1079 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201080 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271081
[email protected]1c773ea12009-04-28 19:58:421082 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521083 request.method = "POST";
1084 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271085 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521086 request.load_flags = 0;
1087
[email protected]3fe8d2f82013-10-17 08:56:071088 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271089 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271091
initial.commit586acc5fe2008-07-26 22:42:521092 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351093 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1094 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1095 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061096 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521097 };
[email protected]31a2bfe2010-02-09 08:03:391098 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071099 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521100
[email protected]49639fa2011-12-20 23:22:411101 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521102
[email protected]49639fa2011-12-20 23:22:411103 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421104 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521105
1106 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421107 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521108
[email protected]1c773ea12009-04-28 19:58:421109 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501110 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521111
[email protected]90499482013-06-01 00:39:501112 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251113 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521114
1115 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571116 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421117 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251118 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521119}
1120
[email protected]3a2d3662009-03-27 03:49:141121// This test is almost the same as Ignores100 above, but the response contains
1122// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571123// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021124TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421125 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141126 request.method = "GET";
1127 request.url = GURL("http://www.foo.com/");
1128 request.load_flags = 0;
1129
[email protected]3fe8d2f82013-10-17 08:56:071130 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271131 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271133
[email protected]3a2d3662009-03-27 03:49:141134 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571135 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1136 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141137 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061138 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141139 };
[email protected]31a2bfe2010-02-09 08:03:391140 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071141 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141142
[email protected]49639fa2011-12-20 23:22:411143 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141144
[email protected]49639fa2011-12-20 23:22:411145 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421146 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141147
1148 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421149 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141150
[email protected]1c773ea12009-04-28 19:58:421151 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501152 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141153
[email protected]90499482013-06-01 00:39:501154 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141155 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1156
1157 std::string response_data;
1158 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421159 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141160 EXPECT_EQ("hello world", response_data);
1161}
1162
[email protected]23e482282013-06-14 16:08:021163TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381164 HttpRequestInfo request;
1165 request.method = "POST";
1166 request.url = GURL("http://www.foo.com/");
1167 request.load_flags = 0;
1168
[email protected]3fe8d2f82013-10-17 08:56:071169 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271170 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271172
[email protected]ee9410e72010-01-07 01:42:381173 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061174 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1175 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381176 };
[email protected]31a2bfe2010-02-09 08:03:391177 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071178 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381179
[email protected]49639fa2011-12-20 23:22:411180 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381181
[email protected]49639fa2011-12-20 23:22:411182 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381183 EXPECT_EQ(ERR_IO_PENDING, rv);
1184
1185 rv = callback.WaitForResult();
1186 EXPECT_EQ(OK, rv);
1187
1188 std::string response_data;
1189 rv = ReadTransaction(trans.get(), &response_data);
1190 EXPECT_EQ(OK, rv);
1191 EXPECT_EQ("", response_data);
1192}
1193
[email protected]23e482282013-06-14 16:08:021194TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381195 HttpRequestInfo request;
1196 request.method = "POST";
1197 request.url = GURL("http://www.foo.com/");
1198 request.load_flags = 0;
1199
[email protected]3fe8d2f82013-10-17 08:56:071200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271201 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1203
[email protected]cb9bf6ca2011-01-28 13:15:271204
[email protected]ee9410e72010-01-07 01:42:381205 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061206 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381207 };
[email protected]31a2bfe2010-02-09 08:03:391208 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071209 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381210
[email protected]49639fa2011-12-20 23:22:411211 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381212
[email protected]49639fa2011-12-20 23:22:411213 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381214 EXPECT_EQ(ERR_IO_PENDING, rv);
1215
1216 rv = callback.WaitForResult();
1217 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1218}
1219
[email protected]23e482282013-06-14 16:08:021220void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511221 const MockWrite* write_failure,
1222 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421223 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521224 request.method = "GET";
1225 request.url = GURL("http://www.foo.com/");
1226 request.load_flags = 0;
1227
[email protected]58e32bb2013-01-21 18:23:251228 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071229 session_deps_.net_log = &net_log;
1230 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271231
[email protected]202965992011-12-07 23:04:511232 // Written data for successfully sending both requests.
1233 MockWrite data1_writes[] = {
1234 MockWrite("GET / HTTP/1.1\r\n"
1235 "Host: www.foo.com\r\n"
1236 "Connection: keep-alive\r\n\r\n"),
1237 MockWrite("GET / HTTP/1.1\r\n"
1238 "Host: www.foo.com\r\n"
1239 "Connection: keep-alive\r\n\r\n")
1240 };
1241
1242 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521243 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351244 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1245 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061246 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521247 };
[email protected]202965992011-12-07 23:04:511248
1249 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491250 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511251 data1_writes[1] = *write_failure;
1252 } else {
1253 ASSERT_TRUE(read_failure);
1254 data1_reads[2] = *read_failure;
1255 }
1256
1257 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1258 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071259 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521260
1261 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351262 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1263 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061264 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521265 };
[email protected]31a2bfe2010-02-09 08:03:391266 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071267 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521268
1269 const char* kExpectedResponseData[] = {
1270 "hello", "world"
1271 };
1272
[email protected]58e32bb2013-01-21 18:23:251273 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521274 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411275 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521276
[email protected]262eec82013-03-19 21:01:361277 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521279
[email protected]49639fa2011-12-20 23:22:411280 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421281 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521282
1283 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421284 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521285
[email protected]58e32bb2013-01-21 18:23:251286 LoadTimingInfo load_timing_info;
1287 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1288 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1289 if (i == 0) {
1290 first_socket_log_id = load_timing_info.socket_log_id;
1291 } else {
1292 // The second request should be using a new socket.
1293 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1294 }
1295
[email protected]1c773ea12009-04-28 19:58:421296 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501297 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521298
[email protected]90499482013-06-01 00:39:501299 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251300 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521301
1302 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571303 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421304 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251305 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521306 }
1307}
[email protected]3d2a59b2008-09-26 19:44:251308
[email protected]a34f61ee2014-03-18 20:59:491309void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1310 const MockWrite* write_failure,
1311 const MockRead* read_failure) {
1312 HttpRequestInfo request;
1313 request.method = "GET";
1314 request.url = GURL("http://www.foo.com/");
1315 request.load_flags = 0;
1316
1317 CapturingNetLog net_log;
1318 session_deps_.net_log = &net_log;
1319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1320
1321 // Written data for successfully sending a request.
1322 MockWrite data1_writes[] = {
1323 MockWrite("GET / HTTP/1.1\r\n"
1324 "Host: www.foo.com\r\n"
1325 "Connection: keep-alive\r\n\r\n"),
1326 };
1327
1328 // Read results for the first request.
1329 MockRead data1_reads[] = {
1330 MockRead(ASYNC, OK),
1331 };
1332
1333 if (write_failure) {
1334 ASSERT_FALSE(read_failure);
1335 data1_writes[0] = *write_failure;
1336 } else {
1337 ASSERT_TRUE(read_failure);
1338 data1_reads[0] = *read_failure;
1339 }
1340
1341 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1342 data1_writes, arraysize(data1_writes));
1343 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1344
1345 MockRead data2_reads[] = {
1346 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1347 MockRead("hello"),
1348 MockRead(ASYNC, OK),
1349 };
1350 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1351 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1352
1353 // Preconnect a socket.
1354 net::SSLConfig ssl_config;
1355 session->ssl_config_service()->GetSSLConfig(&ssl_config);
1356 if (session->http_stream_factory()->has_next_protos())
1357 ssl_config.next_protos = session->http_stream_factory()->next_protos();
1358 session->http_stream_factory()->PreconnectStreams(
1359 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1360 // Wait for the preconnect to complete.
1361 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1362 base::RunLoop().RunUntilIdle();
1363 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
1364
1365 // Make the request.
1366 TestCompletionCallback callback;
1367
1368 scoped_ptr<HttpTransaction> trans(
1369 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1370
1371 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1372 EXPECT_EQ(ERR_IO_PENDING, rv);
1373
1374 rv = callback.WaitForResult();
1375 EXPECT_EQ(OK, rv);
1376
1377 LoadTimingInfo load_timing_info;
1378 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1379 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1380
1381 const HttpResponseInfo* response = trans->GetResponseInfo();
1382 ASSERT_TRUE(response != NULL);
1383
1384 EXPECT_TRUE(response->headers.get() != NULL);
1385 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1386
1387 std::string response_data;
1388 rv = ReadTransaction(trans.get(), &response_data);
1389 EXPECT_EQ(OK, rv);
1390 EXPECT_EQ("hello", response_data);
1391}
1392
[email protected]23e482282013-06-14 16:08:021393TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231394 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061395 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511396 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1397}
1398
[email protected]23e482282013-06-14 16:08:021399TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061400 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511401 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251402}
1403
[email protected]23e482282013-06-14 16:08:021404TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061405 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511406 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251407}
1408
[email protected]a34f61ee2014-03-18 20:59:491409TEST_P(HttpNetworkTransactionTest,
1410 PreconnectErrorNotConnectedOnWrite) {
1411 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1412 PreconnectErrorResendRequestTest(&write_failure, NULL);
1413}
1414
1415TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1416 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1417 PreconnectErrorResendRequestTest(NULL, &read_failure);
1418}
1419
1420TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1421 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1422 PreconnectErrorResendRequestTest(NULL, &read_failure);
1423}
1424
[email protected]23e482282013-06-14 16:08:021425TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421426 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251427 request.method = "GET";
1428 request.url = GURL("http://www.google.com/");
1429 request.load_flags = 0;
1430
[email protected]3fe8d2f82013-10-17 08:56:071431 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271432 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271434
[email protected]3d2a59b2008-09-26 19:44:251435 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061436 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351437 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1438 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061439 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251440 };
[email protected]31a2bfe2010-02-09 08:03:391441 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071442 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251443
[email protected]49639fa2011-12-20 23:22:411444 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251445
[email protected]49639fa2011-12-20 23:22:411446 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421447 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251448
1449 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421450 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251451
[email protected]1c773ea12009-04-28 19:58:421452 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251453 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251454}
1455
1456// What do various browsers do when the server closes a non-keepalive
1457// connection without sending any response header or body?
1458//
1459// IE7: error page
1460// Safari 3.1.2 (Windows): error page
1461// Firefox 3.0.1: blank page
1462// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421463// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1464// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021465TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251466 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061467 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351468 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1469 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061470 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251471 };
[email protected]31a2bfe2010-02-09 08:03:391472 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1473 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421474 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251475}
[email protected]038e9a32008-10-08 22:40:161476
[email protected]1826a402014-01-08 15:40:481477// Test that network access can be deferred and resumed.
1478TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1479 HttpRequestInfo request;
1480 request.method = "GET";
1481 request.url = GURL("http://www.google.com/");
1482 request.load_flags = 0;
1483
1484 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1485 scoped_ptr<HttpTransaction> trans(
1486 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1487
1488 // Defer on OnBeforeNetworkStart.
1489 BeforeNetworkStartHandler net_start_handler(true); // defer
1490 trans->SetBeforeNetworkStartCallback(
1491 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1492 base::Unretained(&net_start_handler)));
1493
1494 MockRead data_reads[] = {
1495 MockRead("HTTP/1.0 200 OK\r\n"),
1496 MockRead("Content-Length: 5\r\n\r\n"),
1497 MockRead("hello"),
1498 MockRead(SYNCHRONOUS, 0),
1499 };
1500 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1501 session_deps_.socket_factory->AddSocketDataProvider(&data);
1502
1503 TestCompletionCallback callback;
1504
1505 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1506 EXPECT_EQ(ERR_IO_PENDING, rv);
1507 base::MessageLoop::current()->RunUntilIdle();
1508
1509 // Should have deferred for network start.
1510 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1511 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1512 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1513
1514 trans->ResumeNetworkStart();
1515 rv = callback.WaitForResult();
1516 EXPECT_EQ(OK, rv);
1517 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1518
1519 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1520 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1521 if (rv == ERR_IO_PENDING)
1522 rv = callback.WaitForResult();
1523 EXPECT_EQ(5, rv);
1524 trans.reset();
1525}
1526
1527// Test that network use can be deferred and canceled.
1528TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1529 HttpRequestInfo request;
1530 request.method = "GET";
1531 request.url = GURL("http://www.google.com/");
1532 request.load_flags = 0;
1533
1534 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1535 scoped_ptr<HttpTransaction> trans(
1536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1537
1538 // Defer on OnBeforeNetworkStart.
1539 BeforeNetworkStartHandler net_start_handler(true); // defer
1540 trans->SetBeforeNetworkStartCallback(
1541 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1542 base::Unretained(&net_start_handler)));
1543
1544 TestCompletionCallback callback;
1545
1546 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1547 EXPECT_EQ(ERR_IO_PENDING, rv);
1548 base::MessageLoop::current()->RunUntilIdle();
1549
1550 // Should have deferred for network start.
1551 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1552 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1553 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1554}
1555
[email protected]7a5378b2012-11-04 03:25:171556// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1557// tests. There was a bug causing HttpNetworkTransaction to hang in the
1558// destructor in such situations.
1559// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021560TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171561 HttpRequestInfo request;
1562 request.method = "GET";
1563 request.url = GURL("http://www.google.com/");
1564 request.load_flags = 0;
1565
[email protected]bb88e1d32013-05-03 23:11:071566 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361567 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501568 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171569
1570 MockRead data_reads[] = {
1571 MockRead("HTTP/1.0 200 OK\r\n"),
1572 MockRead("Connection: keep-alive\r\n"),
1573 MockRead("Content-Length: 100\r\n\r\n"),
1574 MockRead("hello"),
1575 MockRead(SYNCHRONOUS, 0),
1576 };
1577 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071578 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171579
1580 TestCompletionCallback callback;
1581
1582 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1583 EXPECT_EQ(ERR_IO_PENDING, rv);
1584
1585 rv = callback.WaitForResult();
1586 EXPECT_EQ(OK, rv);
1587
1588 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501589 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171590 if (rv == ERR_IO_PENDING)
1591 rv = callback.WaitForResult();
1592 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501593 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171594 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1595
1596 trans.reset();
[email protected]2da659e2013-05-23 20:51:341597 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171598 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1599}
1600
[email protected]23e482282013-06-14 16:08:021601TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171602 HttpRequestInfo request;
1603 request.method = "GET";
1604 request.url = GURL("http://www.google.com/");
1605 request.load_flags = 0;
1606
[email protected]bb88e1d32013-05-03 23:11:071607 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361608 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171610
1611 MockRead data_reads[] = {
1612 MockRead("HTTP/1.0 200 OK\r\n"),
1613 MockRead("Connection: keep-alive\r\n"),
1614 MockRead("Content-Length: 100\r\n\r\n"),
1615 MockRead(SYNCHRONOUS, 0),
1616 };
1617 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171619
1620 TestCompletionCallback callback;
1621
1622 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1623 EXPECT_EQ(ERR_IO_PENDING, rv);
1624
1625 rv = callback.WaitForResult();
1626 EXPECT_EQ(OK, rv);
1627
1628 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501629 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171630 if (rv == ERR_IO_PENDING)
1631 rv = callback.WaitForResult();
1632 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1633
1634 trans.reset();
[email protected]2da659e2013-05-23 20:51:341635 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171636 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1637}
1638
[email protected]0b0bf032010-09-21 18:08:501639// Test that we correctly reuse a keep-alive connection after not explicitly
1640// reading the body.
[email protected]23e482282013-06-14 16:08:021641TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131642 HttpRequestInfo request;
1643 request.method = "GET";
1644 request.url = GURL("http://www.foo.com/");
1645 request.load_flags = 0;
1646
[email protected]58e32bb2013-01-21 18:23:251647 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071648 session_deps_.net_log = &net_log;
1649 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271650
[email protected]0b0bf032010-09-21 18:08:501651 // Note that because all these reads happen in the same
1652 // StaticSocketDataProvider, it shows that the same socket is being reused for
1653 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131654 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501655 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1656 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131657 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501658 MockRead("HTTP/1.1 302 Found\r\n"
1659 "Content-Length: 0\r\n\r\n"),
1660 MockRead("HTTP/1.1 302 Found\r\n"
1661 "Content-Length: 5\r\n\r\n"
1662 "hello"),
1663 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1664 "Content-Length: 0\r\n\r\n"),
1665 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1666 "Content-Length: 5\r\n\r\n"
1667 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131668 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1669 MockRead("hello"),
1670 };
1671 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071672 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131673
1674 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061675 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131676 };
1677 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071678 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131679
[email protected]0b0bf032010-09-21 18:08:501680 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1681 std::string response_lines[kNumUnreadBodies];
1682
[email protected]58e32bb2013-01-21 18:23:251683 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501684 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411685 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131686
[email protected]262eec82013-03-19 21:01:361687 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131689
[email protected]49639fa2011-12-20 23:22:411690 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131691 EXPECT_EQ(ERR_IO_PENDING, rv);
1692
1693 rv = callback.WaitForResult();
1694 EXPECT_EQ(OK, rv);
1695
[email protected]58e32bb2013-01-21 18:23:251696 LoadTimingInfo load_timing_info;
1697 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1698 if (i == 0) {
1699 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1700 first_socket_log_id = load_timing_info.socket_log_id;
1701 } else {
1702 TestLoadTimingReused(load_timing_info);
1703 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1704 }
1705
[email protected]fc31d6a42010-06-24 18:05:131706 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501707 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131708
[email protected]90499482013-06-01 00:39:501709 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501710 response_lines[i] = response->headers->GetStatusLine();
1711
1712 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131713 }
[email protected]0b0bf032010-09-21 18:08:501714
1715 const char* const kStatusLines[] = {
1716 "HTTP/1.1 204 No Content",
1717 "HTTP/1.1 205 Reset Content",
1718 "HTTP/1.1 304 Not Modified",
1719 "HTTP/1.1 302 Found",
1720 "HTTP/1.1 302 Found",
1721 "HTTP/1.1 301 Moved Permanently",
1722 "HTTP/1.1 301 Moved Permanently",
1723 };
1724
1725 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1726 forgot_to_update_kStatusLines);
1727
1728 for (int i = 0; i < kNumUnreadBodies; ++i)
1729 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1730
[email protected]49639fa2011-12-20 23:22:411731 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361732 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411734 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501735 EXPECT_EQ(ERR_IO_PENDING, rv);
1736 rv = callback.WaitForResult();
1737 EXPECT_EQ(OK, rv);
1738 const HttpResponseInfo* response = trans->GetResponseInfo();
1739 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501740 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501741 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1742 std::string response_data;
1743 rv = ReadTransaction(trans.get(), &response_data);
1744 EXPECT_EQ(OK, rv);
1745 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131746}
1747
[email protected]038e9a32008-10-08 22:40:161748// Test the request-challenge-retry sequence for basic auth.
1749// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021750TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421751 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161752 request.method = "GET";
1753 request.url = GURL("http://www.google.com/");
1754 request.load_flags = 0;
1755
[email protected]58e32bb2013-01-21 18:23:251756 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071757 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071758 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271759 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271761
[email protected]f9ee6b52008-11-08 06:46:231762 MockWrite data_writes1[] = {
1763 MockWrite("GET / HTTP/1.1\r\n"
1764 "Host: www.google.com\r\n"
1765 "Connection: keep-alive\r\n\r\n"),
1766 };
1767
[email protected]038e9a32008-10-08 22:40:161768 MockRead data_reads1[] = {
1769 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1770 // Give a couple authenticate options (only the middle one is actually
1771 // supported).
[email protected]22927ad2009-09-21 19:56:191772 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161773 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1774 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1775 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1776 // Large content-length -- won't matter, as connection will be reset.
1777 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061778 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161779 };
1780
1781 // After calling trans->RestartWithAuth(), this is the request we should
1782 // be issuing -- the final header line contains the credentials.
1783 MockWrite data_writes2[] = {
1784 MockWrite("GET / HTTP/1.1\r\n"
1785 "Host: www.google.com\r\n"
1786 "Connection: keep-alive\r\n"
1787 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1788 };
1789
1790 // Lastly, the server responds with the actual content.
1791 MockRead data_reads2[] = {
1792 MockRead("HTTP/1.0 200 OK\r\n"),
1793 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1794 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061795 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161796 };
1797
[email protected]31a2bfe2010-02-09 08:03:391798 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1799 data_writes1, arraysize(data_writes1));
1800 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1801 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071802 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1803 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161804
[email protected]49639fa2011-12-20 23:22:411805 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161806
[email protected]49639fa2011-12-20 23:22:411807 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421808 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161809
1810 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421811 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161812
[email protected]58e32bb2013-01-21 18:23:251813 LoadTimingInfo load_timing_info1;
1814 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1815 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1816
[email protected]b8015c42013-12-24 15:18:191817 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1818 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1819
[email protected]1c773ea12009-04-28 19:58:421820 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501821 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041822 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161823
[email protected]49639fa2011-12-20 23:22:411824 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161825
[email protected]49639fa2011-12-20 23:22:411826 rv = trans->RestartWithAuth(
1827 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421828 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161829
1830 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421831 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161832
[email protected]58e32bb2013-01-21 18:23:251833 LoadTimingInfo load_timing_info2;
1834 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1835 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1836 // The load timing after restart should have a new socket ID, and times after
1837 // those of the first load timing.
1838 EXPECT_LE(load_timing_info1.receive_headers_end,
1839 load_timing_info2.connect_timing.connect_start);
1840 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1841
[email protected]b8015c42013-12-24 15:18:191842 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1843 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1844
[email protected]038e9a32008-10-08 22:40:161845 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501846 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161847 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1848 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161849}
1850
[email protected]23e482282013-06-14 16:08:021851TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461852 HttpRequestInfo request;
1853 request.method = "GET";
1854 request.url = GURL("http://www.google.com/");
1855 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1856
[email protected]3fe8d2f82013-10-17 08:56:071857 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271858 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071859 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271860
[email protected]861fcd52009-08-26 02:33:461861 MockWrite data_writes[] = {
1862 MockWrite("GET / HTTP/1.1\r\n"
1863 "Host: www.google.com\r\n"
1864 "Connection: keep-alive\r\n\r\n"),
1865 };
1866
1867 MockRead data_reads[] = {
1868 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1869 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1870 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1871 // Large content-length -- won't matter, as connection will be reset.
1872 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061873 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461874 };
1875
[email protected]31a2bfe2010-02-09 08:03:391876 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1877 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071878 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411879 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461880
[email protected]49639fa2011-12-20 23:22:411881 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461882 EXPECT_EQ(ERR_IO_PENDING, rv);
1883
1884 rv = callback.WaitForResult();
1885 EXPECT_EQ(0, rv);
1886
[email protected]b8015c42013-12-24 15:18:191887 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
1888 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
1889
[email protected]861fcd52009-08-26 02:33:461890 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501891 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461892 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1893}
1894
[email protected]2d2697f92009-02-18 21:00:321895// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1896// connection.
[email protected]23e482282013-06-14 16:08:021897TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421898 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321899 request.method = "GET";
1900 request.url = GURL("http://www.google.com/");
1901 request.load_flags = 0;
1902
[email protected]58e32bb2013-01-21 18:23:251903 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071904 session_deps_.net_log = &log;
1905 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271906
[email protected]2d2697f92009-02-18 21:00:321907 MockWrite data_writes1[] = {
1908 MockWrite("GET / HTTP/1.1\r\n"
1909 "Host: www.google.com\r\n"
1910 "Connection: keep-alive\r\n\r\n"),
1911
1912 // After calling trans->RestartWithAuth(), this is the request we should
1913 // be issuing -- the final header line contains the credentials.
1914 MockWrite("GET / HTTP/1.1\r\n"
1915 "Host: www.google.com\r\n"
1916 "Connection: keep-alive\r\n"
1917 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1918 };
1919
1920 MockRead data_reads1[] = {
1921 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1922 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1923 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1924 MockRead("Content-Length: 14\r\n\r\n"),
1925 MockRead("Unauthorized\r\n"),
1926
1927 // Lastly, the server responds with the actual content.
1928 MockRead("HTTP/1.1 200 OK\r\n"),
1929 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501930 MockRead("Content-Length: 5\r\n\r\n"),
1931 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321932 };
1933
[email protected]2d0a4f92011-05-05 16:38:461934 // If there is a regression where we disconnect a Keep-Alive
1935 // connection during an auth roundtrip, we'll end up reading this.
1936 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061937 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461938 };
1939
[email protected]31a2bfe2010-02-09 08:03:391940 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1941 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461942 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1943 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071944 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1945 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321946
[email protected]49639fa2011-12-20 23:22:411947 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321948
[email protected]262eec82013-03-19 21:01:361949 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501950 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411951 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421952 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321953
1954 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421955 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321956
[email protected]58e32bb2013-01-21 18:23:251957 LoadTimingInfo load_timing_info1;
1958 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1959 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1960
[email protected]1c773ea12009-04-28 19:58:421961 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501962 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041963 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321964
[email protected]49639fa2011-12-20 23:22:411965 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321966
[email protected]49639fa2011-12-20 23:22:411967 rv = trans->RestartWithAuth(
1968 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421969 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321970
1971 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421972 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321973
[email protected]58e32bb2013-01-21 18:23:251974 LoadTimingInfo load_timing_info2;
1975 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1976 TestLoadTimingReused(load_timing_info2);
1977 // The load timing after restart should have the same socket ID, and times
1978 // those of the first load timing.
1979 EXPECT_LE(load_timing_info1.receive_headers_end,
1980 load_timing_info2.send_start);
1981 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1982
[email protected]2d2697f92009-02-18 21:00:321983 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501984 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321985 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501986 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:191987
1988 std::string response_data;
1989 rv = ReadTransaction(trans.get(), &response_data);
1990 EXPECT_EQ(OK, rv);
1991 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1992 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:321993}
1994
1995// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1996// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021997TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421998 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321999 request.method = "GET";
2000 request.url = GURL("http://www.google.com/");
2001 request.load_flags = 0;
2002
[email protected]bb88e1d32013-05-03 23:11:072003 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272004
[email protected]2d2697f92009-02-18 21:00:322005 MockWrite data_writes1[] = {
2006 MockWrite("GET / HTTP/1.1\r\n"
2007 "Host: www.google.com\r\n"
2008 "Connection: keep-alive\r\n\r\n"),
2009
2010 // After calling trans->RestartWithAuth(), this is the request we should
2011 // be issuing -- the final header line contains the credentials.
2012 MockWrite("GET / HTTP/1.1\r\n"
2013 "Host: www.google.com\r\n"
2014 "Connection: keep-alive\r\n"
2015 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2016 };
2017
[email protected]2d2697f92009-02-18 21:00:322018 MockRead data_reads1[] = {
2019 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2020 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312021 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322022
2023 // Lastly, the server responds with the actual content.
2024 MockRead("HTTP/1.1 200 OK\r\n"),
2025 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502026 MockRead("Content-Length: 5\r\n\r\n"),
2027 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322028 };
2029
[email protected]2d0a4f92011-05-05 16:38:462030 // An incorrect reconnect would cause this to be read.
2031 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062032 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462033 };
2034
[email protected]31a2bfe2010-02-09 08:03:392035 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2036 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462037 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2038 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072039 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2040 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322041
[email protected]49639fa2011-12-20 23:22:412042 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322043
[email protected]262eec82013-03-19 21:01:362044 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502045 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412046 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422047 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322048
2049 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422050 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322051
[email protected]1c773ea12009-04-28 19:58:422052 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502053 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042054 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322055
[email protected]49639fa2011-12-20 23:22:412056 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322057
[email protected]49639fa2011-12-20 23:22:412058 rv = trans->RestartWithAuth(
2059 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422060 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322061
2062 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422063 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322064
2065 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502066 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322067 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502068 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322069}
2070
2071// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2072// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022073TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422074 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322075 request.method = "GET";
2076 request.url = GURL("http://www.google.com/");
2077 request.load_flags = 0;
2078
[email protected]bb88e1d32013-05-03 23:11:072079 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272080
[email protected]2d2697f92009-02-18 21:00:322081 MockWrite data_writes1[] = {
2082 MockWrite("GET / HTTP/1.1\r\n"
2083 "Host: www.google.com\r\n"
2084 "Connection: keep-alive\r\n\r\n"),
2085
2086 // After calling trans->RestartWithAuth(), this is the request we should
2087 // be issuing -- the final header line contains the credentials.
2088 MockWrite("GET / HTTP/1.1\r\n"
2089 "Host: www.google.com\r\n"
2090 "Connection: keep-alive\r\n"
2091 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2092 };
2093
2094 // Respond with 5 kb of response body.
2095 std::string large_body_string("Unauthorized");
2096 large_body_string.append(5 * 1024, ' ');
2097 large_body_string.append("\r\n");
2098
2099 MockRead data_reads1[] = {
2100 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2101 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2102 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2103 // 5134 = 12 + 5 * 1024 + 2
2104 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062105 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322106
2107 // Lastly, the server responds with the actual content.
2108 MockRead("HTTP/1.1 200 OK\r\n"),
2109 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502110 MockRead("Content-Length: 5\r\n\r\n"),
2111 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322112 };
2113
[email protected]2d0a4f92011-05-05 16:38:462114 // An incorrect reconnect would cause this to be read.
2115 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062116 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462117 };
2118
[email protected]31a2bfe2010-02-09 08:03:392119 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2120 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462121 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2122 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322125
[email protected]49639fa2011-12-20 23:22:412126 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322127
[email protected]262eec82013-03-19 21:01:362128 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502129 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412130 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422131 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322132
2133 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422134 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322135
[email protected]1c773ea12009-04-28 19:58:422136 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502137 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042138 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322139
[email protected]49639fa2011-12-20 23:22:412140 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322141
[email protected]49639fa2011-12-20 23:22:412142 rv = trans->RestartWithAuth(
2143 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422144 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322145
2146 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422147 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322148
2149 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502150 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322151 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502152 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322153}
2154
2155// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312156// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022157TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312158 HttpRequestInfo request;
2159 request.method = "GET";
2160 request.url = GURL("http://www.google.com/");
2161 request.load_flags = 0;
2162
[email protected]bb88e1d32013-05-03 23:11:072163 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272164
[email protected]11203f012009-11-12 23:02:312165 MockWrite data_writes1[] = {
2166 MockWrite("GET / HTTP/1.1\r\n"
2167 "Host: www.google.com\r\n"
2168 "Connection: keep-alive\r\n\r\n"),
2169 // This simulates the seemingly successful write to a closed connection
2170 // if the bug is not fixed.
2171 MockWrite("GET / HTTP/1.1\r\n"
2172 "Host: www.google.com\r\n"
2173 "Connection: keep-alive\r\n"
2174 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2175 };
2176
2177 MockRead data_reads1[] = {
2178 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2179 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2180 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2181 MockRead("Content-Length: 14\r\n\r\n"),
2182 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062183 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312184 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062185 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312186 };
2187
2188 // After calling trans->RestartWithAuth(), this is the request we should
2189 // be issuing -- the final header line contains the credentials.
2190 MockWrite data_writes2[] = {
2191 MockWrite("GET / HTTP/1.1\r\n"
2192 "Host: www.google.com\r\n"
2193 "Connection: keep-alive\r\n"
2194 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2195 };
2196
2197 // Lastly, the server responds with the actual content.
2198 MockRead data_reads2[] = {
2199 MockRead("HTTP/1.1 200 OK\r\n"),
2200 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502201 MockRead("Content-Length: 5\r\n\r\n"),
2202 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312203 };
2204
[email protected]31a2bfe2010-02-09 08:03:392205 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2206 data_writes1, arraysize(data_writes1));
2207 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2208 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072209 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2210 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312211
[email protected]49639fa2011-12-20 23:22:412212 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312213
[email protected]262eec82013-03-19 21:01:362214 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412216 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312217 EXPECT_EQ(ERR_IO_PENDING, rv);
2218
2219 rv = callback1.WaitForResult();
2220 EXPECT_EQ(OK, rv);
2221
2222 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502223 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042224 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312225
[email protected]49639fa2011-12-20 23:22:412226 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312227
[email protected]49639fa2011-12-20 23:22:412228 rv = trans->RestartWithAuth(
2229 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312230 EXPECT_EQ(ERR_IO_PENDING, rv);
2231
2232 rv = callback2.WaitForResult();
2233 EXPECT_EQ(OK, rv);
2234
2235 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502236 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312237 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502238 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312239}
2240
[email protected]394816e92010-08-03 07:38:592241// Test the request-challenge-retry sequence for basic auth, over a connection
2242// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022243TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592244 HttpRequestInfo request;
2245 request.method = "GET";
2246 request.url = GURL("https://www.google.com/");
2247 // when the no authentication data flag is set.
2248 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2249
[email protected]cb9bf6ca2011-01-28 13:15:272250 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072251 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202252 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292253 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072254 session_deps_.net_log = log.bound().net_log();
2255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272256
[email protected]394816e92010-08-03 07:38:592257 // Since we have proxy, should try to establish tunnel.
2258 MockWrite data_writes1[] = {
2259 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2260 "Host: www.google.com\r\n"
2261 "Proxy-Connection: keep-alive\r\n\r\n"),
2262
2263 // After calling trans->RestartWithAuth(), this is the request we should
2264 // be issuing -- the final header line contains the credentials.
2265 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2266 "Host: www.google.com\r\n"
2267 "Proxy-Connection: keep-alive\r\n"
2268 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2269
2270 MockWrite("GET / HTTP/1.1\r\n"
2271 "Host: www.google.com\r\n"
2272 "Connection: keep-alive\r\n\r\n"),
2273 };
2274
2275 // The proxy responds to the connect with a 407, using a persistent
2276 // connection.
2277 MockRead data_reads1[] = {
2278 // No credentials.
2279 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2280 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2281 MockRead("Proxy-Connection: close\r\n\r\n"),
2282
2283 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2284
2285 MockRead("HTTP/1.1 200 OK\r\n"),
2286 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502287 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062288 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592289 };
2290
2291 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2292 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072293 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062294 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072295 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592296
[email protected]49639fa2011-12-20 23:22:412297 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592298
[email protected]262eec82013-03-19 21:01:362299 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502300 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502301
[email protected]49639fa2011-12-20 23:22:412302 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592303 EXPECT_EQ(ERR_IO_PENDING, rv);
2304
2305 rv = callback1.WaitForResult();
2306 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572307 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402308 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592309 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402310 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592311 NetLog::PHASE_NONE);
2312 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402313 entries, pos,
[email protected]394816e92010-08-03 07:38:592314 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2315 NetLog::PHASE_NONE);
2316
2317 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502318 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502319 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592320 EXPECT_EQ(407, response->headers->response_code());
2321 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042322 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592323
[email protected]029c83b62013-01-24 05:28:202324 LoadTimingInfo load_timing_info;
2325 // CONNECT requests and responses are handled at the connect job level, so
2326 // the transaction does not yet have a connection.
2327 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2328
[email protected]49639fa2011-12-20 23:22:412329 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592330
[email protected]49639fa2011-12-20 23:22:412331 rv = trans->RestartWithAuth(
2332 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592333 EXPECT_EQ(ERR_IO_PENDING, rv);
2334
2335 rv = callback2.WaitForResult();
2336 EXPECT_EQ(OK, rv);
2337
2338 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502339 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592340
2341 EXPECT_TRUE(response->headers->IsKeepAlive());
2342 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502343 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592344 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2345
2346 // The password prompt info should not be set.
2347 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502348
[email protected]029c83b62013-01-24 05:28:202349 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2350 TestLoadTimingNotReusedWithPac(load_timing_info,
2351 CONNECT_TIMING_HAS_SSL_TIMES);
2352
[email protected]0b0bf032010-09-21 18:08:502353 trans.reset();
[email protected]102e27c2011-02-23 01:01:312354 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592355}
2356
[email protected]11203f012009-11-12 23:02:312357// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322358// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022359TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272360 HttpRequestInfo request;
2361 request.method = "GET";
2362 request.url = GURL("https://www.google.com/");
2363 // Ensure that proxy authentication is attempted even
2364 // when the no authentication data flag is set.
2365 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2366
[email protected]2d2697f92009-02-18 21:00:322367 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072368 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292369 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072370 session_deps_.net_log = log.bound().net_log();
2371 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322372
[email protected]262eec82013-03-19 21:01:362373 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502374 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322375
[email protected]2d2697f92009-02-18 21:00:322376 // Since we have proxy, should try to establish tunnel.
2377 MockWrite data_writes1[] = {
2378 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452379 "Host: www.google.com\r\n"
2380 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322381
2382 // After calling trans->RestartWithAuth(), this is the request we should
2383 // be issuing -- the final header line contains the credentials.
2384 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2385 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452386 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322387 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2388 };
2389
2390 // The proxy responds to the connect with a 407, using a persistent
2391 // connection.
2392 MockRead data_reads1[] = {
2393 // No credentials.
2394 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2395 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2396 MockRead("Content-Length: 10\r\n\r\n"),
2397 MockRead("0123456789"),
2398
2399 // Wrong credentials (wrong password).
2400 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2401 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2402 MockRead("Content-Length: 10\r\n\r\n"),
2403 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062404 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322405 };
2406
[email protected]31a2bfe2010-02-09 08:03:392407 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2408 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072409 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322410
[email protected]49639fa2011-12-20 23:22:412411 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322412
[email protected]49639fa2011-12-20 23:22:412413 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422414 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322415
2416 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422417 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572418 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402419 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392420 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402421 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392422 NetLog::PHASE_NONE);
2423 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402424 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392425 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2426 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322427
[email protected]1c773ea12009-04-28 19:58:422428 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502429 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502430 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322431 EXPECT_TRUE(response->headers->IsKeepAlive());
2432 EXPECT_EQ(407, response->headers->response_code());
2433 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422434 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042435 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322436
[email protected]49639fa2011-12-20 23:22:412437 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322438
2439 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412440 rv = trans->RestartWithAuth(
2441 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422442 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322443
2444 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422445 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322446
2447 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502448 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502449 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322450 EXPECT_TRUE(response->headers->IsKeepAlive());
2451 EXPECT_EQ(407, response->headers->response_code());
2452 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422453 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042454 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132455
[email protected]e60e47a2010-07-14 03:37:182456 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2457 // out of scope.
[email protected]102e27c2011-02-23 01:01:312458 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322459}
2460
[email protected]a8e9b162009-03-12 00:06:442461// Test that we don't read the response body when we fail to establish a tunnel,
2462// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022463TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272464 HttpRequestInfo request;
2465 request.method = "GET";
2466 request.url = GURL("https://www.google.com/");
2467 request.load_flags = 0;
2468
[email protected]a8e9b162009-03-12 00:06:442469 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072470 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442471
[email protected]bb88e1d32013-05-03 23:11:072472 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442473
[email protected]262eec82013-03-19 21:01:362474 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442476
[email protected]a8e9b162009-03-12 00:06:442477 // Since we have proxy, should try to establish tunnel.
2478 MockWrite data_writes[] = {
2479 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452480 "Host: www.google.com\r\n"
2481 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442482 };
2483
2484 // The proxy responds to the connect with a 407.
2485 MockRead data_reads[] = {
2486 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2487 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2488 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062489 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442490 };
2491
[email protected]31a2bfe2010-02-09 08:03:392492 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2493 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072494 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442495
[email protected]49639fa2011-12-20 23:22:412496 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442497
[email protected]49639fa2011-12-20 23:22:412498 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422499 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442500
2501 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422502 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442503
[email protected]1c773ea12009-04-28 19:58:422504 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502505 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442506
2507 EXPECT_TRUE(response->headers->IsKeepAlive());
2508 EXPECT_EQ(407, response->headers->response_code());
2509 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422510 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442511
2512 std::string response_data;
2513 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422514 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182515
2516 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312517 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442518}
2519
[email protected]8fdbcd22010-05-05 02:54:522520// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2521// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022522TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522523 HttpRequestInfo request;
2524 request.method = "GET";
2525 request.url = GURL("http://www.google.com/");
2526 request.load_flags = 0;
2527
[email protected]cb9bf6ca2011-01-28 13:15:272528 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072529 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272530 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072531 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272532
[email protected]8fdbcd22010-05-05 02:54:522533 MockWrite data_writes1[] = {
2534 MockWrite("GET / HTTP/1.1\r\n"
2535 "Host: www.google.com\r\n"
2536 "Connection: keep-alive\r\n\r\n"),
2537 };
2538
2539 MockRead data_reads1[] = {
2540 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2541 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2542 // Large content-length -- won't matter, as connection will be reset.
2543 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062544 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522545 };
2546
2547 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2548 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072549 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522550
[email protected]49639fa2011-12-20 23:22:412551 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522552
[email protected]49639fa2011-12-20 23:22:412553 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522554 EXPECT_EQ(ERR_IO_PENDING, rv);
2555
2556 rv = callback.WaitForResult();
2557 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2558}
2559
[email protected]7a67a8152010-11-05 18:31:102560// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2561// through a non-authenticating proxy. The request should fail with
2562// ERR_UNEXPECTED_PROXY_AUTH.
2563// Note that it is impossible to detect if an HTTP server returns a 407 through
2564// a non-authenticating proxy - there is nothing to indicate whether the
2565// response came from the proxy or the server, so it is treated as if the proxy
2566// issued the challenge.
[email protected]23e482282013-06-14 16:08:022567TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232568 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272569 HttpRequestInfo request;
2570 request.method = "GET";
2571 request.url = GURL("https://www.google.com/");
2572
[email protected]bb88e1d32013-05-03 23:11:072573 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292574 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072575 session_deps_.net_log = log.bound().net_log();
2576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102577
[email protected]7a67a8152010-11-05 18:31:102578 // Since we have proxy, should try to establish tunnel.
2579 MockWrite data_writes1[] = {
2580 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2581 "Host: www.google.com\r\n"
2582 "Proxy-Connection: keep-alive\r\n\r\n"),
2583
2584 MockWrite("GET / HTTP/1.1\r\n"
2585 "Host: www.google.com\r\n"
2586 "Connection: keep-alive\r\n\r\n"),
2587 };
2588
2589 MockRead data_reads1[] = {
2590 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2591
2592 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2593 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2594 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062595 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102596 };
2597
2598 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2599 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072600 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062601 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072602 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102603
[email protected]49639fa2011-12-20 23:22:412604 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102605
[email protected]262eec82013-03-19 21:01:362606 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102608
[email protected]49639fa2011-12-20 23:22:412609 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102610 EXPECT_EQ(ERR_IO_PENDING, rv);
2611
2612 rv = callback1.WaitForResult();
2613 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572614 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402615 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102616 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402617 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102618 NetLog::PHASE_NONE);
2619 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402620 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102621 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2622 NetLog::PHASE_NONE);
2623}
[email protected]2df19bb2010-08-25 20:13:462624
[email protected]029c83b62013-01-24 05:28:202625// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022626TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202627 HttpRequestInfo request1;
2628 request1.method = "GET";
2629 request1.url = GURL("https://www.google.com/1");
2630
2631 HttpRequestInfo request2;
2632 request2.method = "GET";
2633 request2.url = GURL("https://www.google.com/2");
2634
2635 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072636 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202637 ProxyService::CreateFixed("PROXY myproxy:70"));
2638 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]029c83b62013-01-24 05:28:202641
2642 // 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 /1 HTTP/1.1\r\n"
2649 "Host: www.google.com\r\n"
2650 "Connection: keep-alive\r\n\r\n"),
2651
2652 MockWrite("GET /2 HTTP/1.1\r\n"
2653 "Host: www.google.com\r\n"
2654 "Connection: keep-alive\r\n\r\n"),
2655 };
2656
2657 // The proxy responds to the connect with a 407, using a persistent
2658 // connection.
2659 MockRead data_reads1[] = {
2660 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2661
2662 MockRead("HTTP/1.1 200 OK\r\n"),
2663 MockRead("Content-Length: 1\r\n\r\n"),
2664 MockRead(SYNCHRONOUS, "1"),
2665
2666 MockRead("HTTP/1.1 200 OK\r\n"),
2667 MockRead("Content-Length: 2\r\n\r\n"),
2668 MockRead(SYNCHRONOUS, "22"),
2669 };
2670
2671 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2672 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072673 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202674 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202676
2677 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362678 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202680
2681 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2682 EXPECT_EQ(ERR_IO_PENDING, rv);
2683
2684 rv = callback1.WaitForResult();
2685 EXPECT_EQ(OK, rv);
2686
2687 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2688 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502689 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202690 EXPECT_EQ(1, response1->headers->GetContentLength());
2691
2692 LoadTimingInfo load_timing_info1;
2693 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2694 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2695
2696 trans1.reset();
2697
2698 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362699 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502700 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202701
2702 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2703 EXPECT_EQ(ERR_IO_PENDING, rv);
2704
2705 rv = callback2.WaitForResult();
2706 EXPECT_EQ(OK, rv);
2707
2708 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2709 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502710 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202711 EXPECT_EQ(2, response2->headers->GetContentLength());
2712
2713 LoadTimingInfo load_timing_info2;
2714 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2715 TestLoadTimingReused(load_timing_info2);
2716
2717 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2718
2719 trans2.reset();
2720 session->CloseAllConnections();
2721}
2722
2723// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022724TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202725 HttpRequestInfo request1;
2726 request1.method = "GET";
2727 request1.url = GURL("https://www.google.com/1");
2728
2729 HttpRequestInfo request2;
2730 request2.method = "GET";
2731 request2.url = GURL("https://www.google.com/2");
2732
2733 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072734 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202735 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2736 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072737 session_deps_.net_log = log.bound().net_log();
2738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202739
2740 // Since we have proxy, should try to establish tunnel.
2741 MockWrite data_writes1[] = {
2742 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2743 "Host: www.google.com\r\n"
2744 "Proxy-Connection: keep-alive\r\n\r\n"),
2745
2746 MockWrite("GET /1 HTTP/1.1\r\n"
2747 "Host: www.google.com\r\n"
2748 "Connection: keep-alive\r\n\r\n"),
2749
2750 MockWrite("GET /2 HTTP/1.1\r\n"
2751 "Host: www.google.com\r\n"
2752 "Connection: keep-alive\r\n\r\n"),
2753 };
2754
2755 // The proxy responds to the connect with a 407, using a persistent
2756 // connection.
2757 MockRead data_reads1[] = {
2758 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2759
2760 MockRead("HTTP/1.1 200 OK\r\n"),
2761 MockRead("Content-Length: 1\r\n\r\n"),
2762 MockRead(SYNCHRONOUS, "1"),
2763
2764 MockRead("HTTP/1.1 200 OK\r\n"),
2765 MockRead("Content-Length: 2\r\n\r\n"),
2766 MockRead(SYNCHRONOUS, "22"),
2767 };
2768
2769 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2770 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072771 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202772 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202774
2775 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362776 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502777 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202778
2779 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2780 EXPECT_EQ(ERR_IO_PENDING, rv);
2781
2782 rv = callback1.WaitForResult();
2783 EXPECT_EQ(OK, rv);
2784
2785 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2786 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502787 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202788 EXPECT_EQ(1, response1->headers->GetContentLength());
2789
2790 LoadTimingInfo load_timing_info1;
2791 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2792 TestLoadTimingNotReusedWithPac(load_timing_info1,
2793 CONNECT_TIMING_HAS_SSL_TIMES);
2794
2795 trans1.reset();
2796
2797 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362798 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202800
2801 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2802 EXPECT_EQ(ERR_IO_PENDING, rv);
2803
2804 rv = callback2.WaitForResult();
2805 EXPECT_EQ(OK, rv);
2806
2807 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2808 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502809 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202810 EXPECT_EQ(2, response2->headers->GetContentLength());
2811
2812 LoadTimingInfo load_timing_info2;
2813 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2814 TestLoadTimingReusedWithPac(load_timing_info2);
2815
2816 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2817
2818 trans2.reset();
2819 session->CloseAllConnections();
2820}
2821
[email protected]2df19bb2010-08-25 20:13:462822// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022823TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272824 HttpRequestInfo request;
2825 request.method = "GET";
2826 request.url = GURL("http://www.google.com/");
2827
[email protected]2df19bb2010-08-25 20:13:462828 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072829 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112830 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292831 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072832 session_deps_.net_log = log.bound().net_log();
2833 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462834
[email protected]2df19bb2010-08-25 20:13:462835 // Since we have proxy, should use full url
2836 MockWrite data_writes1[] = {
2837 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2838 "Host: www.google.com\r\n"
2839 "Proxy-Connection: keep-alive\r\n\r\n"),
2840 };
2841
2842 MockRead data_reads1[] = {
2843 MockRead("HTTP/1.1 200 OK\r\n"),
2844 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2845 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062846 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462847 };
2848
2849 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2850 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072851 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062852 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072853 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462854
[email protected]49639fa2011-12-20 23:22:412855 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462856
[email protected]262eec82013-03-19 21:01:362857 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502858 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502859
[email protected]49639fa2011-12-20 23:22:412860 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462861 EXPECT_EQ(ERR_IO_PENDING, rv);
2862
2863 rv = callback1.WaitForResult();
2864 EXPECT_EQ(OK, rv);
2865
[email protected]58e32bb2013-01-21 18:23:252866 LoadTimingInfo load_timing_info;
2867 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2868 TestLoadTimingNotReused(load_timing_info,
2869 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2870
[email protected]2df19bb2010-08-25 20:13:462871 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502872 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462873
2874 EXPECT_TRUE(response->headers->IsKeepAlive());
2875 EXPECT_EQ(200, response->headers->response_code());
2876 EXPECT_EQ(100, response->headers->GetContentLength());
2877 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2878
2879 // The password prompt info should not be set.
2880 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2881}
2882
[email protected]7642b5ae2010-09-01 20:55:172883// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022884TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272885 HttpRequestInfo request;
2886 request.method = "GET";
2887 request.url = GURL("http://www.google.com/");
2888 request.load_flags = 0;
2889
[email protected]7642b5ae2010-09-01 20:55:172890 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072891 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112892 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292893 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072894 session_deps_.net_log = log.bound().net_log();
2895 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172896
[email protected]7642b5ae2010-09-01 20:55:172897 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462898 scoped_ptr<SpdyFrame> req(
2899 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172900 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2901
[email protected]23e482282013-06-14 16:08:022902 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2903 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172904 MockRead spdy_reads[] = {
2905 CreateMockRead(*resp),
2906 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062907 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172908 };
2909
[email protected]dd54bd82012-07-19 23:44:572910 DelayedSocketData spdy_data(
2911 1, // wait for one write to finish before reading.
2912 spdy_reads, arraysize(spdy_reads),
2913 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072914 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172915
[email protected]8ddf8322012-02-23 18:08:062916 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022917 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072918 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172919
[email protected]49639fa2011-12-20 23:22:412920 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172921
[email protected]262eec82013-03-19 21:01:362922 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502924
[email protected]49639fa2011-12-20 23:22:412925 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172926 EXPECT_EQ(ERR_IO_PENDING, rv);
2927
2928 rv = callback1.WaitForResult();
2929 EXPECT_EQ(OK, rv);
2930
[email protected]58e32bb2013-01-21 18:23:252931 LoadTimingInfo load_timing_info;
2932 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2933 TestLoadTimingNotReused(load_timing_info,
2934 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2935
[email protected]7642b5ae2010-09-01 20:55:172936 const HttpResponseInfo* response = trans->GetResponseInfo();
2937 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502938 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172939 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2940
2941 std::string response_data;
2942 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232943 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172944}
2945
[email protected]dc7bd1c52010-11-12 00:01:132946// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022947TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272948 HttpRequestInfo request;
2949 request.method = "GET";
2950 request.url = GURL("http://www.google.com/");
2951 request.load_flags = 0;
2952
[email protected]79cb5c12011-09-12 13:12:042953 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072954 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042955 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292956 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072957 session_deps_.net_log = log.bound().net_log();
2958 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132959
[email protected]dc7bd1c52010-11-12 00:01:132960 // The first request will be a bare GET, the second request will be a
2961 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192962 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462963 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132964 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462965 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132966 };
[email protected]ff98d7f02012-03-22 21:44:192967 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462968 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2969 arraysize(kExtraAuthorizationHeaders) / 2,
2970 false,
2971 3,
2972 LOWEST,
2973 false));
[email protected]dc7bd1c52010-11-12 00:01:132974 MockWrite spdy_writes[] = {
2975 CreateMockWrite(*req_get, 1),
2976 CreateMockWrite(*req_get_authorization, 4),
2977 };
2978
2979 // The first response is a 407 proxy authentication challenge, and the second
2980 // response will be a 200 response since the second request includes a valid
2981 // Authorization header.
2982 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462983 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132984 };
[email protected]ff98d7f02012-03-22 21:44:192985 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022986 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132987 "407 Proxy Authentication Required",
2988 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2989 1));
[email protected]ff98d7f02012-03-22 21:44:192990 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022991 spdy_util_.ConstructSpdyBodyFrame(1, true));
2992 scoped_ptr<SpdyFrame> resp_data(
2993 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2994 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132995 MockRead spdy_reads[] = {
2996 CreateMockRead(*resp_authentication, 2),
2997 CreateMockRead(*body_authentication, 3),
2998 CreateMockRead(*resp_data, 5),
2999 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063000 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133001 };
3002
[email protected]dd54bd82012-07-19 23:44:573003 OrderedSocketData data(
3004 spdy_reads, arraysize(spdy_reads),
3005 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073006 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133007
[email protected]8ddf8322012-02-23 18:08:063008 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023009 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133011
[email protected]49639fa2011-12-20 23:22:413012 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133013
[email protected]262eec82013-03-19 21:01:363014 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503015 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133016
[email protected]49639fa2011-12-20 23:22:413017 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133018 EXPECT_EQ(ERR_IO_PENDING, rv);
3019
3020 rv = callback1.WaitForResult();
3021 EXPECT_EQ(OK, rv);
3022
3023 const HttpResponseInfo* const response = trans->GetResponseInfo();
3024
3025 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503026 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133027 EXPECT_EQ(407, response->headers->response_code());
3028 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043029 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133030
[email protected]49639fa2011-12-20 23:22:413031 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133032
[email protected]49639fa2011-12-20 23:22:413033 rv = trans->RestartWithAuth(
3034 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133035 EXPECT_EQ(ERR_IO_PENDING, rv);
3036
3037 rv = callback2.WaitForResult();
3038 EXPECT_EQ(OK, rv);
3039
3040 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3041
3042 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503043 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133044 EXPECT_EQ(200, response_restart->headers->response_code());
3045 // The password prompt info should not be set.
3046 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3047}
3048
[email protected]d9da5fe2010-10-13 22:37:163049// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023050TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273051 HttpRequestInfo request;
3052 request.method = "GET";
3053 request.url = GURL("https://www.google.com/");
3054 request.load_flags = 0;
3055
[email protected]d9da5fe2010-10-13 22:37:163056 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073057 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113058 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293059 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073060 session_deps_.net_log = log.bound().net_log();
3061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163062
[email protected]262eec82013-03-19 21:01:363063 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163065
[email protected]d9da5fe2010-10-13 22:37:163066 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543067 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3068 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163069 // fetch https://www.google.com/ via HTTP
3070
3071 const char get[] = "GET / HTTP/1.1\r\n"
3072 "Host: www.google.com\r\n"
3073 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193074 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023075 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3076 scoped_ptr<SpdyFrame> conn_resp(
3077 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163078 const char resp[] = "HTTP/1.1 200 OK\r\n"
3079 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193080 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023081 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193082 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023083 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193084 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203085 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043086
3087 MockWrite spdy_writes[] = {
3088 CreateMockWrite(*connect, 1),
3089 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463090 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043091 };
3092
[email protected]d9da5fe2010-10-13 22:37:163093 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063094 CreateMockRead(*conn_resp, 2, ASYNC),
3095 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3096 CreateMockRead(*wrapped_body, 6, ASYNC),
3097 CreateMockRead(*wrapped_body, 7, ASYNC),
3098 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163099 };
3100
[email protected]dd54bd82012-07-19 23:44:573101 OrderedSocketData spdy_data(
3102 spdy_reads, arraysize(spdy_reads),
3103 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073104 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163105
[email protected]8ddf8322012-02-23 18:08:063106 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023107 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073108 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063109 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163110 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463111 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163113
[email protected]49639fa2011-12-20 23:22:413114 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163115
[email protected]49639fa2011-12-20 23:22:413116 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163117 EXPECT_EQ(ERR_IO_PENDING, rv);
3118
3119 rv = callback1.WaitForResult();
3120 EXPECT_EQ(OK, rv);
3121
[email protected]58e32bb2013-01-21 18:23:253122 LoadTimingInfo load_timing_info;
3123 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3124 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3125
[email protected]d9da5fe2010-10-13 22:37:163126 const HttpResponseInfo* response = trans->GetResponseInfo();
3127 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503128 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3130
3131 std::string response_data;
3132 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3133 EXPECT_EQ("1234567890", response_data);
3134}
3135
3136// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023137TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273138 HttpRequestInfo request;
3139 request.method = "GET";
3140 request.url = GURL("https://www.google.com/");
3141 request.load_flags = 0;
3142
[email protected]d9da5fe2010-10-13 22:37:163143 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073144 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113145 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293146 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073147 session_deps_.net_log = log.bound().net_log();
3148 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163149
[email protected]262eec82013-03-19 21:01:363150 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163152
[email protected]d9da5fe2010-10-13 22:37:163153 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543154 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3155 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163156 // fetch https://www.google.com/ via SPDY
3157 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463158 scoped_ptr<SpdyFrame> get(
3159 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023160 scoped_ptr<SpdyFrame> wrapped_get(
3161 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3162 scoped_ptr<SpdyFrame> conn_resp(
3163 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3164 scoped_ptr<SpdyFrame> get_resp(
3165 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193166 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023167 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3168 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3169 scoped_ptr<SpdyFrame> wrapped_body(
3170 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193171 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203172 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193173 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203174 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043175
3176 MockWrite spdy_writes[] = {
3177 CreateMockWrite(*connect, 1),
3178 CreateMockWrite(*wrapped_get, 3),
3179 CreateMockWrite(*window_update_get_resp, 5),
3180 CreateMockWrite(*window_update_body, 7),
3181 };
3182
[email protected]d9da5fe2010-10-13 22:37:163183 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063184 CreateMockRead(*conn_resp, 2, ASYNC),
3185 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3186 CreateMockRead(*wrapped_body, 6, ASYNC),
3187 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163188 };
3189
[email protected]dd54bd82012-07-19 23:44:573190 OrderedSocketData spdy_data(
3191 spdy_reads, arraysize(spdy_reads),
3192 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073193 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163194
[email protected]8ddf8322012-02-23 18:08:063195 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023196 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073197 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063198 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023199 ssl2.SetNextProto(GetParam());
3200 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163202
[email protected]49639fa2011-12-20 23:22:413203 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163204
[email protected]49639fa2011-12-20 23:22:413205 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163206 EXPECT_EQ(ERR_IO_PENDING, rv);
3207
3208 rv = callback1.WaitForResult();
3209 EXPECT_EQ(OK, rv);
3210
[email protected]58e32bb2013-01-21 18:23:253211 LoadTimingInfo load_timing_info;
3212 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3213 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3214
[email protected]d9da5fe2010-10-13 22:37:163215 const HttpResponseInfo* response = trans->GetResponseInfo();
3216 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503217 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163218 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3219
3220 std::string response_data;
3221 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233222 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163223}
3224
3225// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023226TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273227 HttpRequestInfo request;
3228 request.method = "GET";
3229 request.url = GURL("https://www.google.com/");
3230 request.load_flags = 0;
3231
[email protected]d9da5fe2010-10-13 22:37:163232 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073233 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113234 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293235 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073236 session_deps_.net_log = log.bound().net_log();
3237 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163238
[email protected]262eec82013-03-19 21:01:363239 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163241
[email protected]d9da5fe2010-10-13 22:37:163242 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543243 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3244 LOWEST));
[email protected]c10b20852013-05-15 21:29:203245 scoped_ptr<SpdyFrame> get(
3246 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163247
3248 MockWrite spdy_writes[] = {
3249 CreateMockWrite(*connect, 1),
3250 CreateMockWrite(*get, 3),
3251 };
3252
[email protected]23e482282013-06-14 16:08:023253 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3254 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163255 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063256 CreateMockRead(*resp, 2, ASYNC),
3257 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163258 };
3259
[email protected]dd54bd82012-07-19 23:44:573260 OrderedSocketData spdy_data(
3261 spdy_reads, arraysize(spdy_reads),
3262 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073263 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163264
[email protected]8ddf8322012-02-23 18:08:063265 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023266 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073267 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063268 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023269 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163271
[email protected]49639fa2011-12-20 23:22:413272 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163273
[email protected]49639fa2011-12-20 23:22:413274 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163275 EXPECT_EQ(ERR_IO_PENDING, rv);
3276
3277 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173278 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163279
[email protected]4eddbc732012-08-09 05:40:173280 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163281}
3282
[email protected]f6c63db52013-02-02 00:35:223283// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3284// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023285TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223286 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3287 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073288 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223289 "https://proxy:70"));
3290 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073291 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223292 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073293 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223294
3295 HttpRequestInfo request1;
3296 request1.method = "GET";
3297 request1.url = GURL("https://www.google.com/");
3298 request1.load_flags = 0;
3299
3300 HttpRequestInfo request2;
3301 request2.method = "GET";
3302 request2.url = GURL("https://news.google.com/");
3303 request2.load_flags = 0;
3304
3305 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543306 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3307 LOWEST));
[email protected]23e482282013-06-14 16:08:023308 scoped_ptr<SpdyFrame> conn_resp1(
3309 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223310
3311 // Fetch https://www.google.com/ via HTTP.
3312 const char get1[] = "GET / HTTP/1.1\r\n"
3313 "Host: www.google.com\r\n"
3314 "Connection: keep-alive\r\n\r\n";
3315 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023316 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223317 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3318 "Content-Length: 1\r\n\r\n";
3319 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023320 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3321 scoped_ptr<SpdyFrame> wrapped_body1(
3322 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223323 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203324 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223325
3326 // CONNECT to news.google.com:443 via SPDY.
3327 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023328 spdy_util_.GetMethodKey(), "CONNECT",
3329 spdy_util_.GetPathKey(), "news.google.com:443",
3330 spdy_util_.GetHostKey(), "news.google.com",
3331 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223332 };
3333 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233334 spdy_util_.ConstructSpdyControlFrame(NULL,
3335 0,
3336 /*compressed*/ false,
3337 3,
3338 LOWEST,
3339 SYN_STREAM,
3340 CONTROL_FLAG_NONE,
3341 kConnectHeaders2,
3342 arraysize(kConnectHeaders2),
3343 0));
[email protected]23e482282013-06-14 16:08:023344 scoped_ptr<SpdyFrame> conn_resp2(
3345 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223346
3347 // Fetch https://news.google.com/ via HTTP.
3348 const char get2[] = "GET / HTTP/1.1\r\n"
3349 "Host: news.google.com\r\n"
3350 "Connection: keep-alive\r\n\r\n";
3351 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023352 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223353 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3354 "Content-Length: 2\r\n\r\n";
3355 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023356 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223357 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023358 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223359
3360 MockWrite spdy_writes[] = {
3361 CreateMockWrite(*connect1, 0),
3362 CreateMockWrite(*wrapped_get1, 2),
3363 CreateMockWrite(*connect2, 5),
3364 CreateMockWrite(*wrapped_get2, 7),
3365 };
3366
3367 MockRead spdy_reads[] = {
3368 CreateMockRead(*conn_resp1, 1, ASYNC),
3369 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3370 CreateMockRead(*wrapped_body1, 4, ASYNC),
3371 CreateMockRead(*conn_resp2, 6, ASYNC),
3372 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3373 CreateMockRead(*wrapped_body2, 9, ASYNC),
3374 MockRead(ASYNC, 0, 10),
3375 };
3376
3377 DeterministicSocketData spdy_data(
3378 spdy_reads, arraysize(spdy_reads),
3379 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073380 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223381
3382 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023383 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073384 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223385 SSLSocketDataProvider ssl2(ASYNC, OK);
3386 ssl2.was_npn_negotiated = false;
3387 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073388 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223389 SSLSocketDataProvider ssl3(ASYNC, OK);
3390 ssl3.was_npn_negotiated = false;
3391 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073392 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223393
3394 TestCompletionCallback callback;
3395
[email protected]262eec82013-03-19 21:01:363396 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503397 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223398 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3399 EXPECT_EQ(ERR_IO_PENDING, rv);
3400 // The first connect and request, each of their responses, and the body.
3401 spdy_data.RunFor(5);
3402
3403 rv = callback.WaitForResult();
3404 EXPECT_EQ(OK, rv);
3405
3406 LoadTimingInfo load_timing_info;
3407 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3408 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3409
3410 const HttpResponseInfo* response = trans->GetResponseInfo();
3411 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503412 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223413 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3414
3415 std::string response_data;
3416 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503417 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223418
[email protected]262eec82013-03-19 21:01:363419 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223421 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3422 EXPECT_EQ(ERR_IO_PENDING, rv);
3423
3424 // The second connect and request, each of their responses, and the body.
3425 spdy_data.RunFor(5);
3426 rv = callback.WaitForResult();
3427 EXPECT_EQ(OK, rv);
3428
3429 LoadTimingInfo load_timing_info2;
3430 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3431 // Even though the SPDY connection is reused, a new tunnelled connection has
3432 // to be created, so the socket's load timing looks like a fresh connection.
3433 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3434
3435 // The requests should have different IDs, since they each are using their own
3436 // separate stream.
3437 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3438
[email protected]90499482013-06-01 00:39:503439 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223440}
3441
3442// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3443// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023444TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223445 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3446 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073447 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223448 "https://proxy:70"));
3449 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073450 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223451 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073452 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223453
3454 HttpRequestInfo request1;
3455 request1.method = "GET";
3456 request1.url = GURL("https://www.google.com/");
3457 request1.load_flags = 0;
3458
3459 HttpRequestInfo request2;
3460 request2.method = "GET";
3461 request2.url = GURL("https://www.google.com/2");
3462 request2.load_flags = 0;
3463
3464 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543465 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3466 LOWEST));
[email protected]23e482282013-06-14 16:08:023467 scoped_ptr<SpdyFrame> conn_resp1(
3468 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223469
3470 // Fetch https://www.google.com/ via HTTP.
3471 const char get1[] = "GET / HTTP/1.1\r\n"
3472 "Host: www.google.com\r\n"
3473 "Connection: keep-alive\r\n\r\n";
3474 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023475 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223476 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3477 "Content-Length: 1\r\n\r\n";
3478 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023479 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3480 scoped_ptr<SpdyFrame> wrapped_body1(
3481 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223482 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203483 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223484
3485 // Fetch https://www.google.com/2 via HTTP.
3486 const char get2[] = "GET /2 HTTP/1.1\r\n"
3487 "Host: www.google.com\r\n"
3488 "Connection: keep-alive\r\n\r\n";
3489 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023490 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223491 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3492 "Content-Length: 2\r\n\r\n";
3493 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023494 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223495 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023496 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223497
3498 MockWrite spdy_writes[] = {
3499 CreateMockWrite(*connect1, 0),
3500 CreateMockWrite(*wrapped_get1, 2),
3501 CreateMockWrite(*wrapped_get2, 5),
3502 };
3503
3504 MockRead spdy_reads[] = {
3505 CreateMockRead(*conn_resp1, 1, ASYNC),
3506 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3507 CreateMockRead(*wrapped_body1, 4, ASYNC),
3508 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3509 CreateMockRead(*wrapped_body2, 7, ASYNC),
3510 MockRead(ASYNC, 0, 8),
3511 };
3512
3513 DeterministicSocketData spdy_data(
3514 spdy_reads, arraysize(spdy_reads),
3515 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073516 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223517
3518 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023519 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073520 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223521 SSLSocketDataProvider ssl2(ASYNC, OK);
3522 ssl2.was_npn_negotiated = false;
3523 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073524 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223525
3526 TestCompletionCallback callback;
3527
[email protected]262eec82013-03-19 21:01:363528 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503529 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223530 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3531 EXPECT_EQ(ERR_IO_PENDING, rv);
3532 // The first connect and request, each of their responses, and the body.
3533 spdy_data.RunFor(5);
3534
3535 rv = callback.WaitForResult();
3536 EXPECT_EQ(OK, rv);
3537
3538 LoadTimingInfo load_timing_info;
3539 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3540 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3541
3542 const HttpResponseInfo* response = trans->GetResponseInfo();
3543 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503544 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223545 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3546
3547 std::string response_data;
3548 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503549 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223550 trans.reset();
3551
[email protected]262eec82013-03-19 21:01:363552 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503553 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223554 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3555 EXPECT_EQ(ERR_IO_PENDING, rv);
3556
3557 // The second request, response, and body. There should not be a second
3558 // connect.
3559 spdy_data.RunFor(3);
3560 rv = callback.WaitForResult();
3561 EXPECT_EQ(OK, rv);
3562
3563 LoadTimingInfo load_timing_info2;
3564 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3565 TestLoadTimingReused(load_timing_info2);
3566
3567 // The requests should have the same ID.
3568 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3569
[email protected]90499482013-06-01 00:39:503570 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223571}
3572
3573// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3574// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023575TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223576 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3577 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073578 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223579 "https://proxy:70"));
3580 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073581 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223582 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073583 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223584
3585 HttpRequestInfo request1;
3586 request1.method = "GET";
3587 request1.url = GURL("http://www.google.com/");
3588 request1.load_flags = 0;
3589
3590 HttpRequestInfo request2;
3591 request2.method = "GET";
3592 request2.url = GURL("http://news.google.com/");
3593 request2.load_flags = 0;
3594
3595 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023596 scoped_ptr<SpdyHeaderBlock> headers(
3597 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233598 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023599 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3600 scoped_ptr<SpdyFrame> get_resp1(
3601 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3602 scoped_ptr<SpdyFrame> body1(
3603 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223604
3605 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023606 scoped_ptr<SpdyHeaderBlock> headers2(
3607 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233608 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023609 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3610 scoped_ptr<SpdyFrame> get_resp2(
3611 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3612 scoped_ptr<SpdyFrame> body2(
3613 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223614
3615 MockWrite spdy_writes[] = {
3616 CreateMockWrite(*get1, 0),
3617 CreateMockWrite(*get2, 3),
3618 };
3619
3620 MockRead spdy_reads[] = {
3621 CreateMockRead(*get_resp1, 1, ASYNC),
3622 CreateMockRead(*body1, 2, ASYNC),
3623 CreateMockRead(*get_resp2, 4, ASYNC),
3624 CreateMockRead(*body2, 5, ASYNC),
3625 MockRead(ASYNC, 0, 6),
3626 };
3627
3628 DeterministicSocketData spdy_data(
3629 spdy_reads, arraysize(spdy_reads),
3630 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073631 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223632
3633 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023634 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073635 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223636
3637 TestCompletionCallback callback;
3638
[email protected]262eec82013-03-19 21:01:363639 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223641 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3642 EXPECT_EQ(ERR_IO_PENDING, rv);
3643 spdy_data.RunFor(2);
3644
3645 rv = callback.WaitForResult();
3646 EXPECT_EQ(OK, rv);
3647
3648 LoadTimingInfo load_timing_info;
3649 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3650 TestLoadTimingNotReused(load_timing_info,
3651 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3652
3653 const HttpResponseInfo* response = trans->GetResponseInfo();
3654 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503655 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223656 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3657
3658 std::string response_data;
3659 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503660 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223661 spdy_data.RunFor(1);
3662 EXPECT_EQ(1, callback.WaitForResult());
3663 // Delete the first request, so the second one can reuse the socket.
3664 trans.reset();
3665
[email protected]262eec82013-03-19 21:01:363666 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223668 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3669 EXPECT_EQ(ERR_IO_PENDING, rv);
3670
3671 spdy_data.RunFor(2);
3672 rv = callback.WaitForResult();
3673 EXPECT_EQ(OK, rv);
3674
3675 LoadTimingInfo load_timing_info2;
3676 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3677 TestLoadTimingReused(load_timing_info2);
3678
3679 // The requests should have the same ID.
3680 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3681
[email protected]90499482013-06-01 00:39:503682 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223683 spdy_data.RunFor(1);
3684 EXPECT_EQ(2, callback.WaitForResult());
3685}
3686
[email protected]2df19bb2010-08-25 20:13:463687// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023688TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463689 HttpRequestInfo request;
3690 request.method = "GET";
3691 request.url = GURL("http://www.google.com/");
3692 // when the no authentication data flag is set.
3693 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3694
[email protected]79cb5c12011-09-12 13:12:043695 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073696 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043697 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293698 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073699 session_deps_.net_log = log.bound().net_log();
3700 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273701
[email protected]2df19bb2010-08-25 20:13:463702 // Since we have proxy, should use full url
3703 MockWrite data_writes1[] = {
3704 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3705 "Host: www.google.com\r\n"
3706 "Proxy-Connection: keep-alive\r\n\r\n"),
3707
3708 // After calling trans->RestartWithAuth(), this is the request we should
3709 // be issuing -- the final header line contains the credentials.
3710 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3711 "Host: www.google.com\r\n"
3712 "Proxy-Connection: keep-alive\r\n"
3713 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3714 };
3715
3716 // The proxy responds to the GET with a 407, using a persistent
3717 // connection.
3718 MockRead data_reads1[] = {
3719 // No credentials.
3720 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3721 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3722 MockRead("Proxy-Connection: keep-alive\r\n"),
3723 MockRead("Content-Length: 0\r\n\r\n"),
3724
3725 MockRead("HTTP/1.1 200 OK\r\n"),
3726 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3727 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063728 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463729 };
3730
3731 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3732 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073733 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063734 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073735 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463736
[email protected]49639fa2011-12-20 23:22:413737 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463738
[email protected]262eec82013-03-19 21:01:363739 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503741
[email protected]49639fa2011-12-20 23:22:413742 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463743 EXPECT_EQ(ERR_IO_PENDING, rv);
3744
3745 rv = callback1.WaitForResult();
3746 EXPECT_EQ(OK, rv);
3747
[email protected]58e32bb2013-01-21 18:23:253748 LoadTimingInfo load_timing_info;
3749 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3750 TestLoadTimingNotReused(load_timing_info,
3751 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3752
[email protected]2df19bb2010-08-25 20:13:463753 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503754 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503755 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463756 EXPECT_EQ(407, response->headers->response_code());
3757 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043758 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463759
[email protected]49639fa2011-12-20 23:22:413760 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463761
[email protected]49639fa2011-12-20 23:22:413762 rv = trans->RestartWithAuth(
3763 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463764 EXPECT_EQ(ERR_IO_PENDING, rv);
3765
3766 rv = callback2.WaitForResult();
3767 EXPECT_EQ(OK, rv);
3768
[email protected]58e32bb2013-01-21 18:23:253769 load_timing_info = LoadTimingInfo();
3770 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3771 // Retrying with HTTP AUTH is considered to be reusing a socket.
3772 TestLoadTimingReused(load_timing_info);
3773
[email protected]2df19bb2010-08-25 20:13:463774 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503775 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463776
3777 EXPECT_TRUE(response->headers->IsKeepAlive());
3778 EXPECT_EQ(200, response->headers->response_code());
3779 EXPECT_EQ(100, response->headers->GetContentLength());
3780 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3781
3782 // The password prompt info should not be set.
3783 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3784}
3785
[email protected]23e482282013-06-14 16:08:023786void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083787 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423788 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083789 request.method = "GET";
3790 request.url = GURL("https://www.google.com/");
3791 request.load_flags = 0;
3792
[email protected]cb9bf6ca2011-01-28 13:15:273793 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073794 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073795 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273796
[email protected]c744cf22009-02-27 07:28:083797 // Since we have proxy, should try to establish tunnel.
3798 MockWrite data_writes[] = {
3799 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453800 "Host: www.google.com\r\n"
3801 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083802 };
3803
3804 MockRead data_reads[] = {
3805 status,
3806 MockRead("Content-Length: 10\r\n\r\n"),
3807 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063808 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083809 };
3810
[email protected]31a2bfe2010-02-09 08:03:393811 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3812 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073813 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083814
[email protected]49639fa2011-12-20 23:22:413815 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083816
[email protected]262eec82013-03-19 21:01:363817 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503819
[email protected]49639fa2011-12-20 23:22:413820 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423821 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083822
3823 rv = callback.WaitForResult();
3824 EXPECT_EQ(expected_status, rv);
3825}
3826
[email protected]23e482282013-06-14 16:08:023827void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233828 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083829 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423830 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083831}
3832
[email protected]23e482282013-06-14 16:08:023833TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083834 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3835}
3836
[email protected]23e482282013-06-14 16:08:023837TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083838 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3839}
3840
[email protected]23e482282013-06-14 16:08:023841TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083842 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3843}
3844
[email protected]23e482282013-06-14 16:08:023845TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083846 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3847}
3848
[email protected]23e482282013-06-14 16:08:023849TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083850 ConnectStatusHelper(
3851 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3852}
3853
[email protected]23e482282013-06-14 16:08:023854TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083855 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3856}
3857
[email protected]23e482282013-06-14 16:08:023858TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083859 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3860}
3861
[email protected]23e482282013-06-14 16:08:023862TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083863 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3864}
3865
[email protected]23e482282013-06-14 16:08:023866TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083867 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3868}
3869
[email protected]23e482282013-06-14 16:08:023870TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083871 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3872}
3873
[email protected]23e482282013-06-14 16:08:023874TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083875 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3876}
3877
[email protected]23e482282013-06-14 16:08:023878TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083879 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3880}
3881
[email protected]23e482282013-06-14 16:08:023882TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083883 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3884}
3885
[email protected]23e482282013-06-14 16:08:023886TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083887 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3888}
3889
[email protected]23e482282013-06-14 16:08:023890TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083891 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3892}
3893
[email protected]23e482282013-06-14 16:08:023894TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083895 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3896}
3897
[email protected]23e482282013-06-14 16:08:023898TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083899 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3900}
3901
[email protected]23e482282013-06-14 16:08:023902TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083903 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3904}
3905
[email protected]23e482282013-06-14 16:08:023906TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083907 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3908}
3909
[email protected]23e482282013-06-14 16:08:023910TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083911 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3912}
3913
[email protected]23e482282013-06-14 16:08:023914TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083915 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3916}
3917
[email protected]23e482282013-06-14 16:08:023918TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083919 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3920}
3921
[email protected]23e482282013-06-14 16:08:023922TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083923 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3924}
3925
[email protected]23e482282013-06-14 16:08:023926TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083927 ConnectStatusHelperWithExpectedStatus(
3928 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543929 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083930}
3931
[email protected]23e482282013-06-14 16:08:023932TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083933 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3934}
3935
[email protected]23e482282013-06-14 16:08:023936TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083937 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3938}
3939
[email protected]23e482282013-06-14 16:08:023940TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083941 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3942}
3943
[email protected]23e482282013-06-14 16:08:023944TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083945 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3946}
3947
[email protected]23e482282013-06-14 16:08:023948TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083949 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3950}
3951
[email protected]23e482282013-06-14 16:08:023952TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083953 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3954}
3955
[email protected]23e482282013-06-14 16:08:023956TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083957 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3958}
3959
[email protected]23e482282013-06-14 16:08:023960TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083961 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3962}
3963
[email protected]23e482282013-06-14 16:08:023964TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083965 ConnectStatusHelper(
3966 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3967}
3968
[email protected]23e482282013-06-14 16:08:023969TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083970 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3971}
3972
[email protected]23e482282013-06-14 16:08:023973TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083974 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3975}
3976
[email protected]23e482282013-06-14 16:08:023977TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083978 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3979}
3980
[email protected]23e482282013-06-14 16:08:023981TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083982 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3983}
3984
[email protected]23e482282013-06-14 16:08:023985TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083986 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3987}
3988
[email protected]23e482282013-06-14 16:08:023989TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083990 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3991}
3992
[email protected]23e482282013-06-14 16:08:023993TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083994 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3995}
3996
[email protected]038e9a32008-10-08 22:40:163997// Test the flow when both the proxy server AND origin server require
3998// authentication. Again, this uses basic auth for both since that is
3999// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024000TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274001 HttpRequestInfo request;
4002 request.method = "GET";
4003 request.url = GURL("http://www.google.com/");
4004 request.load_flags = 0;
4005
[email protected]038e9a32008-10-08 22:40:164006 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074007 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4008 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4009
4010 scoped_ptr<HttpTransaction> trans(
4011 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:164012
[email protected]f9ee6b52008-11-08 06:46:234013 MockWrite data_writes1[] = {
4014 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4015 "Host: www.google.com\r\n"
4016 "Proxy-Connection: keep-alive\r\n\r\n"),
4017 };
4018
[email protected]038e9a32008-10-08 22:40:164019 MockRead data_reads1[] = {
4020 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4021 // Give a couple authenticate options (only the middle one is actually
4022 // supported).
[email protected]22927ad2009-09-21 19:56:194023 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164024 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4025 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4026 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4027 // Large content-length -- won't matter, as connection will be reset.
4028 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064029 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164030 };
4031
4032 // After calling trans->RestartWithAuth() the first time, this is the
4033 // request we should be issuing -- the final header line contains the
4034 // proxy's credentials.
4035 MockWrite data_writes2[] = {
4036 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4037 "Host: www.google.com\r\n"
4038 "Proxy-Connection: keep-alive\r\n"
4039 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4040 };
4041
4042 // Now the proxy server lets the request pass through to origin server.
4043 // The origin server responds with a 401.
4044 MockRead data_reads2[] = {
4045 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4046 // Note: We are using the same realm-name as the proxy server. This is
4047 // completely valid, as realms are unique across hosts.
4048 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4049 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4050 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064051 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164052 };
4053
4054 // After calling trans->RestartWithAuth() the second time, we should send
4055 // the credentials for both the proxy and origin server.
4056 MockWrite data_writes3[] = {
4057 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4058 "Host: www.google.com\r\n"
4059 "Proxy-Connection: keep-alive\r\n"
4060 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4061 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4062 };
4063
4064 // Lastly we get the desired content.
4065 MockRead data_reads3[] = {
4066 MockRead("HTTP/1.0 200 OK\r\n"),
4067 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4068 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064069 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164070 };
4071
[email protected]31a2bfe2010-02-09 08:03:394072 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4073 data_writes1, arraysize(data_writes1));
4074 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4075 data_writes2, arraysize(data_writes2));
4076 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4077 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074078 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4079 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4080 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164081
[email protected]49639fa2011-12-20 23:22:414082 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164083
[email protected]49639fa2011-12-20 23:22:414084 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424085 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164086
4087 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424088 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164089
[email protected]1c773ea12009-04-28 19:58:424090 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504091 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044092 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164093
[email protected]49639fa2011-12-20 23:22:414094 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164095
[email protected]49639fa2011-12-20 23:22:414096 rv = trans->RestartWithAuth(
4097 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424098 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164099
4100 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424101 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164102
4103 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504104 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044105 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164106
[email protected]49639fa2011-12-20 23:22:414107 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164108
[email protected]49639fa2011-12-20 23:22:414109 rv = trans->RestartWithAuth(
4110 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424111 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164112
4113 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424114 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164115
4116 response = trans->GetResponseInfo();
4117 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4118 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164119}
[email protected]4ddaf2502008-10-23 18:26:194120
[email protected]ea9dc9a2009-09-05 00:43:324121// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4122// can't hook into its internals to cause it to generate predictable NTLM
4123// authorization headers.
4124#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294125// The NTLM authentication unit tests were generated by capturing the HTTP
4126// requests and responses using Fiddler 2 and inspecting the generated random
4127// bytes in the debugger.
4128
4129// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024130TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424131 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244132 request.method = "GET";
4133 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544134
4135 // Ensure load is not disrupted by flags which suppress behaviour specific
4136 // to other auth schemes.
4137 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244138
[email protected]cb9bf6ca2011-01-28 13:15:274139 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4140 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074141 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274142
[email protected]3f918782009-02-28 01:29:244143 MockWrite data_writes1[] = {
4144 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4145 "Host: 172.22.68.17\r\n"
4146 "Connection: keep-alive\r\n\r\n"),
4147 };
4148
4149 MockRead data_reads1[] = {
4150 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044151 // Negotiate and NTLM are often requested together. However, we only want
4152 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4153 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244154 MockRead("WWW-Authenticate: NTLM\r\n"),
4155 MockRead("Connection: close\r\n"),
4156 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364157 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244158 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064159 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244160 };
4161
4162 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224163 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244164 // request we should be issuing -- the final header line contains a Type
4165 // 1 message.
4166 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4167 "Host: 172.22.68.17\r\n"
4168 "Connection: keep-alive\r\n"
4169 "Authorization: NTLM "
4170 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4171
4172 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4173 // (the credentials for the origin server). The second request continues
4174 // on the same connection.
4175 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4176 "Host: 172.22.68.17\r\n"
4177 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294178 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4179 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4180 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4181 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4182 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244183 };
4184
4185 MockRead data_reads2[] = {
4186 // The origin server responds with a Type 2 message.
4187 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4188 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294189 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244190 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4191 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4192 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4193 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4194 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4195 "BtAAAAAAA=\r\n"),
4196 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364197 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244198 MockRead("You are not authorized to view this page\r\n"),
4199
4200 // Lastly we get the desired content.
4201 MockRead("HTTP/1.1 200 OK\r\n"),
4202 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4203 MockRead("Content-Length: 13\r\n\r\n"),
4204 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064205 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244206 };
4207
[email protected]31a2bfe2010-02-09 08:03:394208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4209 data_writes1, arraysize(data_writes1));
4210 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4211 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074212 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4213 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244214
[email protected]49639fa2011-12-20 23:22:414215 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244216
[email protected]262eec82013-03-19 21:01:364217 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504219
[email protected]49639fa2011-12-20 23:22:414220 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424221 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244222
4223 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424224 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244225
[email protected]0757e7702009-03-27 04:00:224226 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4227
[email protected]1c773ea12009-04-28 19:58:424228 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044229 ASSERT_FALSE(response == NULL);
4230 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244231
[email protected]49639fa2011-12-20 23:22:414232 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254233
[email protected]f3cf9802011-10-28 18:44:584234 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414235 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254236 EXPECT_EQ(ERR_IO_PENDING, rv);
4237
4238 rv = callback2.WaitForResult();
4239 EXPECT_EQ(OK, rv);
4240
4241 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4242
4243 response = trans->GetResponseInfo();
4244 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254245 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4246
[email protected]49639fa2011-12-20 23:22:414247 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244248
[email protected]49639fa2011-12-20 23:22:414249 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424250 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244251
[email protected]0757e7702009-03-27 04:00:224252 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424253 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244254
4255 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504256 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244257 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4258 EXPECT_EQ(13, response->headers->GetContentLength());
4259}
4260
[email protected]385a4672009-03-11 22:21:294261// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024262TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424263 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294264 request.method = "GET";
4265 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4266 request.load_flags = 0;
4267
[email protected]cb9bf6ca2011-01-28 13:15:274268 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4269 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074270 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274271
[email protected]385a4672009-03-11 22:21:294272 MockWrite data_writes1[] = {
4273 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4274 "Host: 172.22.68.17\r\n"
4275 "Connection: keep-alive\r\n\r\n"),
4276 };
4277
4278 MockRead data_reads1[] = {
4279 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044280 // Negotiate and NTLM are often requested together. However, we only want
4281 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4282 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294283 MockRead("WWW-Authenticate: NTLM\r\n"),
4284 MockRead("Connection: close\r\n"),
4285 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364286 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294287 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064288 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294289 };
4290
4291 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224292 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294293 // request we should be issuing -- the final header line contains a Type
4294 // 1 message.
4295 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4296 "Host: 172.22.68.17\r\n"
4297 "Connection: keep-alive\r\n"
4298 "Authorization: NTLM "
4299 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4300
4301 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4302 // (the credentials for the origin server). The second request continues
4303 // on the same connection.
4304 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4305 "Host: 172.22.68.17\r\n"
4306 "Connection: keep-alive\r\n"
4307 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4308 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4309 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4310 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4311 "4Ww7b7E=\r\n\r\n"),
4312 };
4313
4314 MockRead data_reads2[] = {
4315 // The origin server responds with a Type 2 message.
4316 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4317 MockRead("WWW-Authenticate: NTLM "
4318 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4319 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4320 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4321 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4322 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4323 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4324 "BtAAAAAAA=\r\n"),
4325 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364326 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294327 MockRead("You are not authorized to view this page\r\n"),
4328
4329 // Wrong password.
4330 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294331 MockRead("WWW-Authenticate: NTLM\r\n"),
4332 MockRead("Connection: close\r\n"),
4333 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364334 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294335 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064336 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294337 };
4338
4339 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224340 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294341 // request we should be issuing -- the final header line contains a Type
4342 // 1 message.
4343 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4344 "Host: 172.22.68.17\r\n"
4345 "Connection: keep-alive\r\n"
4346 "Authorization: NTLM "
4347 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4348
4349 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4350 // (the credentials for the origin server). The second request continues
4351 // on the same connection.
4352 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4353 "Host: 172.22.68.17\r\n"
4354 "Connection: keep-alive\r\n"
4355 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4356 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4357 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4358 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4359 "+4MUm7c=\r\n\r\n"),
4360 };
4361
4362 MockRead data_reads3[] = {
4363 // The origin server responds with a Type 2 message.
4364 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4365 MockRead("WWW-Authenticate: NTLM "
4366 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4367 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4368 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4369 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4370 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4371 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4372 "BtAAAAAAA=\r\n"),
4373 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364374 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294375 MockRead("You are not authorized to view this page\r\n"),
4376
4377 // Lastly we get the desired content.
4378 MockRead("HTTP/1.1 200 OK\r\n"),
4379 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4380 MockRead("Content-Length: 13\r\n\r\n"),
4381 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064382 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294383 };
4384
[email protected]31a2bfe2010-02-09 08:03:394385 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4386 data_writes1, arraysize(data_writes1));
4387 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4388 data_writes2, arraysize(data_writes2));
4389 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4390 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074391 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4392 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4393 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294394
[email protected]49639fa2011-12-20 23:22:414395 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294396
[email protected]262eec82013-03-19 21:01:364397 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504398 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504399
[email protected]49639fa2011-12-20 23:22:414400 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424401 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294402
4403 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424404 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294405
[email protected]0757e7702009-03-27 04:00:224406 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294407
[email protected]1c773ea12009-04-28 19:58:424408 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504409 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044410 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294411
[email protected]49639fa2011-12-20 23:22:414412 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294413
[email protected]0757e7702009-03-27 04:00:224414 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584415 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414416 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424417 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294418
[email protected]10af5fe72011-01-31 16:17:254419 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424420 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294421
[email protected]0757e7702009-03-27 04:00:224422 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414423 TestCompletionCallback callback3;
4424 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424425 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254426 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424427 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224428 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4429
4430 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044431 ASSERT_FALSE(response == NULL);
4432 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224433
[email protected]49639fa2011-12-20 23:22:414434 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224435
4436 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584437 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414438 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254439 EXPECT_EQ(ERR_IO_PENDING, rv);
4440
4441 rv = callback4.WaitForResult();
4442 EXPECT_EQ(OK, rv);
4443
4444 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4445
[email protected]49639fa2011-12-20 23:22:414446 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254447
4448 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414449 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424450 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224451
4452 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424453 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224454
[email protected]385a4672009-03-11 22:21:294455 response = trans->GetResponseInfo();
4456 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4457 EXPECT_EQ(13, response->headers->GetContentLength());
4458}
[email protected]ea9dc9a2009-09-05 00:43:324459#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294460
[email protected]4ddaf2502008-10-23 18:26:194461// Test reading a server response which has only headers, and no body.
4462// After some maximum number of bytes is consumed, the transaction should
4463// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024464TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424465 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194466 request.method = "GET";
4467 request.url = GURL("http://www.google.com/");
4468 request.load_flags = 0;
4469
[email protected]3fe8d2f82013-10-17 08:56:074470 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274471 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074472 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274473
[email protected]b75b7b2f2009-10-06 00:54:534474 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434475 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534476 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194477
4478 MockRead data_reads[] = {
4479 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064480 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194481 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064482 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194483 };
[email protected]31a2bfe2010-02-09 08:03:394484 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074485 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194486
[email protected]49639fa2011-12-20 23:22:414487 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194488
[email protected]49639fa2011-12-20 23:22:414489 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424490 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194491
4492 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424493 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194494
[email protected]1c773ea12009-04-28 19:58:424495 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194496 EXPECT_TRUE(response == NULL);
4497}
[email protected]f4e426b2008-11-05 00:24:494498
4499// Make sure that we don't try to reuse a TCPClientSocket when failing to
4500// establish tunnel.
4501// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024502TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234503 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274504 HttpRequestInfo request;
4505 request.method = "GET";
4506 request.url = GURL("https://www.google.com/");
4507 request.load_flags = 0;
4508
[email protected]f4e426b2008-11-05 00:24:494509 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074510 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014511
[email protected]bb88e1d32013-05-03 23:11:074512 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494513
[email protected]262eec82013-03-19 21:01:364514 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504515 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494516
[email protected]f4e426b2008-11-05 00:24:494517 // Since we have proxy, should try to establish tunnel.
4518 MockWrite data_writes1[] = {
4519 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454520 "Host: www.google.com\r\n"
4521 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494522 };
4523
[email protected]77848d12008-11-14 00:00:224524 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494525 // connection. Usually a proxy would return 501 (not implemented),
4526 // or 200 (tunnel established).
4527 MockRead data_reads1[] = {
4528 MockRead("HTTP/1.1 404 Not Found\r\n"),
4529 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064530 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494531 };
4532
[email protected]31a2bfe2010-02-09 08:03:394533 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4534 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074535 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494536
[email protected]49639fa2011-12-20 23:22:414537 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494538
[email protected]49639fa2011-12-20 23:22:414539 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424540 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494541
4542 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424543 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494544
[email protected]1c773ea12009-04-28 19:58:424545 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084546 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494547
[email protected]b4404c02009-04-10 16:38:524548 // Empty the current queue. This is necessary because idle sockets are
4549 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344550 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524551
[email protected]f4e426b2008-11-05 00:24:494552 // We now check to make sure the TCPClientSocket was not added back to
4553 // the pool.
[email protected]90499482013-06-01 00:39:504554 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494555 trans.reset();
[email protected]2da659e2013-05-23 20:51:344556 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494557 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504558 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494559}
[email protected]372d34a2008-11-05 21:30:514560
[email protected]1b157c02009-04-21 01:55:404561// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024562TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424563 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404564 request.method = "GET";
4565 request.url = GURL("http://www.google.com/");
4566 request.load_flags = 0;
4567
[email protected]bb88e1d32013-05-03 23:11:074568 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274569
[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]cb9bf6ca2011-01-28 13:15:274572
[email protected]1b157c02009-04-21 01:55:404573 MockRead data_reads[] = {
4574 // A part of the response body is received with the response headers.
4575 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4576 // The rest of the response body is received in two parts.
4577 MockRead("lo"),
4578 MockRead(" world"),
4579 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064580 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404581 };
4582
[email protected]31a2bfe2010-02-09 08:03:394583 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074584 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404585
[email protected]49639fa2011-12-20 23:22:414586 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404587
[email protected]49639fa2011-12-20 23:22:414588 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424589 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404590
4591 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424592 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404593
[email protected]1c773ea12009-04-28 19:58:424594 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504595 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404596
[email protected]90499482013-06-01 00:39:504597 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404598 std::string status_line = response->headers->GetStatusLine();
4599 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4600
[email protected]90499482013-06-01 00:39:504601 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404602
4603 std::string response_data;
4604 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424605 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404606 EXPECT_EQ("hello world", response_data);
4607
4608 // Empty the current queue. This is necessary because idle sockets are
4609 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344610 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404611
4612 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504613 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404614}
4615
[email protected]76a505b2010-08-25 06:23:004616// Make sure that we recycle a SSL socket after reading all of the response
4617// body.
[email protected]23e482282013-06-14 16:08:024618TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004619 HttpRequestInfo request;
4620 request.method = "GET";
4621 request.url = GURL("https://www.google.com/");
4622 request.load_flags = 0;
4623
4624 MockWrite data_writes[] = {
4625 MockWrite("GET / HTTP/1.1\r\n"
4626 "Host: www.google.com\r\n"
4627 "Connection: keep-alive\r\n\r\n"),
4628 };
4629
4630 MockRead data_reads[] = {
4631 MockRead("HTTP/1.1 200 OK\r\n"),
4632 MockRead("Content-Length: 11\r\n\r\n"),
4633 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064634 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004635 };
4636
[email protected]8ddf8322012-02-23 18:08:064637 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074638 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004639
4640 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4641 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074642 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004643
[email protected]49639fa2011-12-20 23:22:414644 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004645
[email protected]bb88e1d32013-05-03 23:11:074646 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364647 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004649
[email protected]49639fa2011-12-20 23:22:414650 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004651
4652 EXPECT_EQ(ERR_IO_PENDING, rv);
4653 EXPECT_EQ(OK, callback.WaitForResult());
4654
4655 const HttpResponseInfo* response = trans->GetResponseInfo();
4656 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504657 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004658 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4659
[email protected]90499482013-06-01 00:39:504660 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004661
4662 std::string response_data;
4663 rv = ReadTransaction(trans.get(), &response_data);
4664 EXPECT_EQ(OK, rv);
4665 EXPECT_EQ("hello world", response_data);
4666
4667 // Empty the current queue. This is necessary because idle sockets are
4668 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344669 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004670
4671 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504672 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004673}
4674
4675// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4676// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024677TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004678 HttpRequestInfo request;
4679 request.method = "GET";
4680 request.url = GURL("https://www.google.com/");
4681 request.load_flags = 0;
4682
4683 MockWrite data_writes[] = {
4684 MockWrite("GET / HTTP/1.1\r\n"
4685 "Host: www.google.com\r\n"
4686 "Connection: keep-alive\r\n\r\n"),
4687 MockWrite("GET / HTTP/1.1\r\n"
4688 "Host: www.google.com\r\n"
4689 "Connection: keep-alive\r\n\r\n"),
4690 };
4691
4692 MockRead data_reads[] = {
4693 MockRead("HTTP/1.1 200 OK\r\n"),
4694 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064695 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004696 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064697 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004698 };
4699
[email protected]8ddf8322012-02-23 18:08:064700 SSLSocketDataProvider ssl(ASYNC, OK);
4701 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004704
4705 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4706 data_writes, arraysize(data_writes));
4707 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4708 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074709 session_deps_.socket_factory->AddSocketDataProvider(&data);
4710 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004711
[email protected]49639fa2011-12-20 23:22:414712 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004713
[email protected]bb88e1d32013-05-03 23:11:074714 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364715 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004717
[email protected]49639fa2011-12-20 23:22:414718 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004719
4720 EXPECT_EQ(ERR_IO_PENDING, rv);
4721 EXPECT_EQ(OK, callback.WaitForResult());
4722
4723 const HttpResponseInfo* response = trans->GetResponseInfo();
4724 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504725 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004726 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4727
[email protected]90499482013-06-01 00:39:504728 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004729
4730 std::string response_data;
4731 rv = ReadTransaction(trans.get(), &response_data);
4732 EXPECT_EQ(OK, rv);
4733 EXPECT_EQ("hello world", response_data);
4734
4735 // Empty the current queue. This is necessary because idle sockets are
4736 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344737 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004738
4739 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504740 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004741
4742 // Now start the second transaction, which should reuse the previous socket.
4743
[email protected]90499482013-06-01 00:39:504744 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004745
[email protected]49639fa2011-12-20 23:22:414746 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004747
4748 EXPECT_EQ(ERR_IO_PENDING, rv);
4749 EXPECT_EQ(OK, callback.WaitForResult());
4750
4751 response = trans->GetResponseInfo();
4752 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504753 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004754 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4755
[email protected]90499482013-06-01 00:39:504756 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004757
4758 rv = ReadTransaction(trans.get(), &response_data);
4759 EXPECT_EQ(OK, rv);
4760 EXPECT_EQ("hello world", response_data);
4761
4762 // Empty the current queue. This is necessary because idle sockets are
4763 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344764 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004765
4766 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504767 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004768}
4769
[email protected]b4404c02009-04-10 16:38:524770// Make sure that we recycle a socket after a zero-length response.
4771// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024772TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424773 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524774 request.method = "GET";
4775 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4776 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4777 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4778 "rt=prt.2642,ol.2649,xjs.2951");
4779 request.load_flags = 0;
4780
[email protected]bb88e1d32013-05-03 23:11:074781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274782
[email protected]262eec82013-03-19 21:01:364783 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274785
[email protected]b4404c02009-04-10 16:38:524786 MockRead data_reads[] = {
4787 MockRead("HTTP/1.1 204 No Content\r\n"
4788 "Content-Length: 0\r\n"
4789 "Content-Type: text/html\r\n\r\n"),
4790 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064791 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524792 };
4793
[email protected]31a2bfe2010-02-09 08:03:394794 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074795 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524796
[email protected]49639fa2011-12-20 23:22:414797 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524798
[email protected]49639fa2011-12-20 23:22:414799 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424800 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524801
4802 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424803 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524804
[email protected]1c773ea12009-04-28 19:58:424805 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504806 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524807
[email protected]90499482013-06-01 00:39:504808 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524809 std::string status_line = response->headers->GetStatusLine();
4810 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4811
[email protected]90499482013-06-01 00:39:504812 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524813
4814 std::string response_data;
4815 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424816 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524817 EXPECT_EQ("", response_data);
4818
4819 // Empty the current queue. This is necessary because idle sockets are
4820 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344821 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524822
4823 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504824 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524825}
4826
[email protected]23e482282013-06-14 16:08:024827TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064828 ScopedVector<UploadElementReader> element_readers;
4829 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204830 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274831
[email protected]1c773ea12009-04-28 19:58:424832 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514833 // Transaction 1: a GET request that succeeds. The socket is recycled
4834 // after use.
4835 request[0].method = "GET";
4836 request[0].url = GURL("http://www.google.com/");
4837 request[0].load_flags = 0;
4838 // Transaction 2: a POST request. Reuses the socket kept alive from
4839 // transaction 1. The first attempts fails when writing the POST data.
4840 // This causes the transaction to retry with a new socket. The second
4841 // attempt succeeds.
4842 request[1].method = "POST";
4843 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274844 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514845 request[1].load_flags = 0;
4846
[email protected]bb88e1d32013-05-03 23:11:074847 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514848
4849 // The first socket is used for transaction 1 and the first attempt of
4850 // transaction 2.
4851
4852 // The response of transaction 1.
4853 MockRead data_reads1[] = {
4854 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4855 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064856 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514857 };
4858 // The mock write results of transaction 1 and the first attempt of
4859 // transaction 2.
4860 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064861 MockWrite(SYNCHRONOUS, 64), // GET
4862 MockWrite(SYNCHRONOUS, 93), // POST
4863 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514864 };
[email protected]31a2bfe2010-02-09 08:03:394865 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4866 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514867
4868 // The second socket is used for the second attempt of transaction 2.
4869
4870 // The response of transaction 2.
4871 MockRead data_reads2[] = {
4872 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4873 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064874 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514875 };
4876 // The mock write results of the second attempt of transaction 2.
4877 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064878 MockWrite(SYNCHRONOUS, 93), // POST
4879 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514880 };
[email protected]31a2bfe2010-02-09 08:03:394881 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4882 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514883
[email protected]bb88e1d32013-05-03 23:11:074884 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4885 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514886
4887 const char* kExpectedResponseData[] = {
4888 "hello world", "welcome"
4889 };
4890
4891 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424892 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514894
[email protected]49639fa2011-12-20 23:22:414895 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514896
[email protected]49639fa2011-12-20 23:22:414897 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424898 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514899
4900 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424901 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514902
[email protected]1c773ea12009-04-28 19:58:424903 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504904 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514905
[email protected]90499482013-06-01 00:39:504906 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514907 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4908
4909 std::string response_data;
4910 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424911 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514912 EXPECT_EQ(kExpectedResponseData[i], response_data);
4913 }
4914}
[email protected]f9ee6b52008-11-08 06:46:234915
4916// Test the request-challenge-retry sequence for basic auth when there is
4917// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164918// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024919TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424920 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234921 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294922 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414923 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294924
[email protected]3fe8d2f82013-10-17 08:56:074925 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274926 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074927 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274928
[email protected]a97cca42009-08-14 01:00:294929 // The password contains an escaped character -- for this test to pass it
4930 // will need to be unescaped by HttpNetworkTransaction.
4931 EXPECT_EQ("b%40r", request.url.password());
4932
[email protected]f9ee6b52008-11-08 06:46:234933 MockWrite data_writes1[] = {
4934 MockWrite("GET / HTTP/1.1\r\n"
4935 "Host: www.google.com\r\n"
4936 "Connection: keep-alive\r\n\r\n"),
4937 };
4938
4939 MockRead data_reads1[] = {
4940 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4941 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4942 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064943 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234944 };
4945
[email protected]2262e3a2012-05-22 16:08:164946 // After the challenge above, the transaction will be restarted using the
4947 // identity from the url (foo, b@r) to answer the challenge.
4948 MockWrite data_writes2[] = {
4949 MockWrite("GET / HTTP/1.1\r\n"
4950 "Host: www.google.com\r\n"
4951 "Connection: keep-alive\r\n"
4952 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4953 };
4954
4955 MockRead data_reads2[] = {
4956 MockRead("HTTP/1.0 200 OK\r\n"),
4957 MockRead("Content-Length: 100\r\n\r\n"),
4958 MockRead(SYNCHRONOUS, OK),
4959 };
4960
[email protected]31a2bfe2010-02-09 08:03:394961 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4962 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164963 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4964 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074965 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4966 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234967
[email protected]49639fa2011-12-20 23:22:414968 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414969 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424970 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234971 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424972 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164973 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4974
4975 TestCompletionCallback callback2;
4976 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4977 EXPECT_EQ(ERR_IO_PENDING, rv);
4978 rv = callback2.WaitForResult();
4979 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224980 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4981
[email protected]2262e3a2012-05-22 16:08:164982 const HttpResponseInfo* response = trans->GetResponseInfo();
4983 ASSERT_TRUE(response != NULL);
4984
4985 // There is no challenge info, since the identity in URL worked.
4986 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4987
4988 EXPECT_EQ(100, response->headers->GetContentLength());
4989
4990 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344991 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164992}
4993
4994// Test the request-challenge-retry sequence for basic auth when there is an
4995// incorrect identity in the URL. The identity from the URL should be used only
4996// once.
[email protected]23e482282013-06-14 16:08:024997TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164998 HttpRequestInfo request;
4999 request.method = "GET";
5000 // Note: the URL has a username:password in it. The password "baz" is
5001 // wrong (should be "bar").
5002 request.url = GURL("http://foo:[email protected]/");
5003
5004 request.load_flags = LOAD_NORMAL;
5005
[email protected]3fe8d2f82013-10-17 08:56:075006 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165007 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:165009
5010 MockWrite data_writes1[] = {
5011 MockWrite("GET / HTTP/1.1\r\n"
5012 "Host: www.google.com\r\n"
5013 "Connection: keep-alive\r\n\r\n"),
5014 };
5015
5016 MockRead data_reads1[] = {
5017 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5018 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5019 MockRead("Content-Length: 10\r\n\r\n"),
5020 MockRead(SYNCHRONOUS, ERR_FAILED),
5021 };
5022
5023 // After the challenge above, the transaction will be restarted using the
5024 // identity from the url (foo, baz) to answer the challenge.
5025 MockWrite data_writes2[] = {
5026 MockWrite("GET / HTTP/1.1\r\n"
5027 "Host: www.google.com\r\n"
5028 "Connection: keep-alive\r\n"
5029 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5030 };
5031
5032 MockRead data_reads2[] = {
5033 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5034 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5035 MockRead("Content-Length: 10\r\n\r\n"),
5036 MockRead(SYNCHRONOUS, ERR_FAILED),
5037 };
5038
5039 // After the challenge above, the transaction will be restarted using the
5040 // identity supplied by the user (foo, bar) to answer the challenge.
5041 MockWrite data_writes3[] = {
5042 MockWrite("GET / HTTP/1.1\r\n"
5043 "Host: www.google.com\r\n"
5044 "Connection: keep-alive\r\n"
5045 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5046 };
5047
5048 MockRead data_reads3[] = {
5049 MockRead("HTTP/1.0 200 OK\r\n"),
5050 MockRead("Content-Length: 100\r\n\r\n"),
5051 MockRead(SYNCHRONOUS, OK),
5052 };
5053
5054 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5055 data_writes1, arraysize(data_writes1));
5056 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5057 data_writes2, arraysize(data_writes2));
5058 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5059 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5061 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5062 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165063
5064 TestCompletionCallback callback1;
5065
5066 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5067 EXPECT_EQ(ERR_IO_PENDING, rv);
5068
5069 rv = callback1.WaitForResult();
5070 EXPECT_EQ(OK, rv);
5071
5072 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5073 TestCompletionCallback callback2;
5074 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5075 EXPECT_EQ(ERR_IO_PENDING, rv);
5076 rv = callback2.WaitForResult();
5077 EXPECT_EQ(OK, rv);
5078 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5079
5080 const HttpResponseInfo* response = trans->GetResponseInfo();
5081 ASSERT_TRUE(response != NULL);
5082 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5083
5084 TestCompletionCallback callback3;
5085 rv = trans->RestartWithAuth(
5086 AuthCredentials(kFoo, kBar), callback3.callback());
5087 EXPECT_EQ(ERR_IO_PENDING, rv);
5088 rv = callback3.WaitForResult();
5089 EXPECT_EQ(OK, rv);
5090 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5091
5092 response = trans->GetResponseInfo();
5093 ASSERT_TRUE(response != NULL);
5094
5095 // There is no challenge info, since the identity worked.
5096 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5097
5098 EXPECT_EQ(100, response->headers->GetContentLength());
5099
[email protected]ea9dc9a2009-09-05 00:43:325100 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345101 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325102}
5103
[email protected]2217aa22013-10-11 03:03:545104
5105// Test the request-challenge-retry sequence for basic auth when there is a
5106// correct identity in the URL, but its use is being suppressed. The identity
5107// from the URL should never be used.
5108TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5109 HttpRequestInfo request;
5110 request.method = "GET";
5111 request.url = GURL("http://foo:[email protected]/");
5112 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5113
[email protected]3fe8d2f82013-10-17 08:56:075114 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545115 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:545117
5118 MockWrite data_writes1[] = {
5119 MockWrite("GET / HTTP/1.1\r\n"
5120 "Host: www.google.com\r\n"
5121 "Connection: keep-alive\r\n\r\n"),
5122 };
5123
5124 MockRead data_reads1[] = {
5125 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5126 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5127 MockRead("Content-Length: 10\r\n\r\n"),
5128 MockRead(SYNCHRONOUS, ERR_FAILED),
5129 };
5130
5131 // After the challenge above, the transaction will be restarted using the
5132 // identity supplied by the user, not the one in the URL, to answer the
5133 // challenge.
5134 MockWrite data_writes3[] = {
5135 MockWrite("GET / HTTP/1.1\r\n"
5136 "Host: www.google.com\r\n"
5137 "Connection: keep-alive\r\n"
5138 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5139 };
5140
5141 MockRead data_reads3[] = {
5142 MockRead("HTTP/1.0 200 OK\r\n"),
5143 MockRead("Content-Length: 100\r\n\r\n"),
5144 MockRead(SYNCHRONOUS, OK),
5145 };
5146
5147 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5148 data_writes1, arraysize(data_writes1));
5149 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5150 data_writes3, arraysize(data_writes3));
5151 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5152 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5153
5154 TestCompletionCallback callback1;
5155 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5156 EXPECT_EQ(ERR_IO_PENDING, rv);
5157 rv = callback1.WaitForResult();
5158 EXPECT_EQ(OK, rv);
5159 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5160
5161 const HttpResponseInfo* response = trans->GetResponseInfo();
5162 ASSERT_TRUE(response != NULL);
5163 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5164
5165 TestCompletionCallback callback3;
5166 rv = trans->RestartWithAuth(
5167 AuthCredentials(kFoo, kBar), callback3.callback());
5168 EXPECT_EQ(ERR_IO_PENDING, rv);
5169 rv = callback3.WaitForResult();
5170 EXPECT_EQ(OK, rv);
5171 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5172
5173 response = trans->GetResponseInfo();
5174 ASSERT_TRUE(response != NULL);
5175
5176 // There is no challenge info, since the identity worked.
5177 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5178 EXPECT_EQ(100, response->headers->GetContentLength());
5179
5180 // Empty the current queue.
5181 base::MessageLoop::current()->RunUntilIdle();
5182}
5183
[email protected]f9ee6b52008-11-08 06:46:235184// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025185TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075186 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235187
5188 // Transaction 1: authenticate (foo, bar) on MyRealm1
5189 {
[email protected]1c773ea12009-04-28 19:58:425190 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235191 request.method = "GET";
5192 request.url = GURL("http://www.google.com/x/y/z");
5193 request.load_flags = 0;
5194
[email protected]262eec82013-03-19 21:01:365195 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505196 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275197
[email protected]f9ee6b52008-11-08 06:46:235198 MockWrite data_writes1[] = {
5199 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5200 "Host: www.google.com\r\n"
5201 "Connection: keep-alive\r\n\r\n"),
5202 };
5203
5204 MockRead data_reads1[] = {
5205 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5206 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5207 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065208 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235209 };
5210
5211 // Resend with authorization (username=foo, password=bar)
5212 MockWrite data_writes2[] = {
5213 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5214 "Host: www.google.com\r\n"
5215 "Connection: keep-alive\r\n"
5216 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5217 };
5218
5219 // Sever accepts the authorization.
5220 MockRead data_reads2[] = {
5221 MockRead("HTTP/1.0 200 OK\r\n"),
5222 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065223 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235224 };
5225
[email protected]31a2bfe2010-02-09 08:03:395226 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5227 data_writes1, arraysize(data_writes1));
5228 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5229 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075230 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5231 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235232
[email protected]49639fa2011-12-20 23:22:415233 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235234
[email protected]49639fa2011-12-20 23:22:415235 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425236 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235237
5238 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425239 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235240
[email protected]1c773ea12009-04-28 19:58:425241 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505242 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045243 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235244
[email protected]49639fa2011-12-20 23:22:415245 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235246
[email protected]49639fa2011-12-20 23:22:415247 rv = trans->RestartWithAuth(
5248 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425249 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235250
5251 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425252 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235253
5254 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505255 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235256 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5257 EXPECT_EQ(100, response->headers->GetContentLength());
5258 }
5259
5260 // ------------------------------------------------------------------------
5261
5262 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5263 {
[email protected]1c773ea12009-04-28 19:58:425264 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235265 request.method = "GET";
5266 // Note that Transaction 1 was at /x/y/z, so this is in the same
5267 // protection space as MyRealm1.
5268 request.url = GURL("http://www.google.com/x/y/a/b");
5269 request.load_flags = 0;
5270
[email protected]262eec82013-03-19 21:01:365271 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505272 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275273
[email protected]f9ee6b52008-11-08 06:46:235274 MockWrite data_writes1[] = {
5275 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5276 "Host: www.google.com\r\n"
5277 "Connection: keep-alive\r\n"
5278 // Send preemptive authorization for MyRealm1
5279 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5280 };
5281
5282 // The server didn't like the preemptive authorization, and
5283 // challenges us for a different realm (MyRealm2).
5284 MockRead data_reads1[] = {
5285 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5286 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5287 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065288 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235289 };
5290
5291 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5292 MockWrite data_writes2[] = {
5293 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5294 "Host: www.google.com\r\n"
5295 "Connection: keep-alive\r\n"
5296 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5297 };
5298
5299 // Sever accepts the authorization.
5300 MockRead data_reads2[] = {
5301 MockRead("HTTP/1.0 200 OK\r\n"),
5302 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065303 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235304 };
5305
[email protected]31a2bfe2010-02-09 08:03:395306 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5307 data_writes1, arraysize(data_writes1));
5308 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5309 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235312
[email protected]49639fa2011-12-20 23:22:415313 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235314
[email protected]49639fa2011-12-20 23:22:415315 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425316 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235317
5318 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425319 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235320
[email protected]1c773ea12009-04-28 19:58:425321 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505322 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045323 ASSERT_TRUE(response->auth_challenge.get());
5324 EXPECT_FALSE(response->auth_challenge->is_proxy);
5325 EXPECT_EQ("www.google.com:80",
5326 response->auth_challenge->challenger.ToString());
5327 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5328 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235329
[email protected]49639fa2011-12-20 23:22:415330 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235331
[email protected]49639fa2011-12-20 23:22:415332 rv = trans->RestartWithAuth(
5333 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425334 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235335
5336 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425337 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235338
5339 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505340 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235341 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5342 EXPECT_EQ(100, response->headers->GetContentLength());
5343 }
5344
5345 // ------------------------------------------------------------------------
5346
5347 // Transaction 3: Resend a request in MyRealm's protection space --
5348 // succeed with preemptive authorization.
5349 {
[email protected]1c773ea12009-04-28 19:58:425350 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235351 request.method = "GET";
5352 request.url = GURL("http://www.google.com/x/y/z2");
5353 request.load_flags = 0;
5354
[email protected]262eec82013-03-19 21:01:365355 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505356 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275357
[email protected]f9ee6b52008-11-08 06:46:235358 MockWrite data_writes1[] = {
5359 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5360 "Host: www.google.com\r\n"
5361 "Connection: keep-alive\r\n"
5362 // The authorization for MyRealm1 gets sent preemptively
5363 // (since the url is in the same protection space)
5364 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5365 };
5366
5367 // Sever accepts the preemptive authorization
5368 MockRead data_reads1[] = {
5369 MockRead("HTTP/1.0 200 OK\r\n"),
5370 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065371 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235372 };
5373
[email protected]31a2bfe2010-02-09 08:03:395374 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5375 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075376 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235377
[email protected]49639fa2011-12-20 23:22:415378 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235379
[email protected]49639fa2011-12-20 23:22:415380 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425381 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235382
5383 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425384 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235385
[email protected]1c773ea12009-04-28 19:58:425386 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505387 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235388
5389 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5390 EXPECT_EQ(100, response->headers->GetContentLength());
5391 }
5392
5393 // ------------------------------------------------------------------------
5394
5395 // Transaction 4: request another URL in MyRealm (however the
5396 // url is not known to belong to the protection space, so no pre-auth).
5397 {
[email protected]1c773ea12009-04-28 19:58:425398 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235399 request.method = "GET";
5400 request.url = GURL("http://www.google.com/x/1");
5401 request.load_flags = 0;
5402
[email protected]262eec82013-03-19 21:01:365403 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275405
[email protected]f9ee6b52008-11-08 06:46:235406 MockWrite data_writes1[] = {
5407 MockWrite("GET /x/1 HTTP/1.1\r\n"
5408 "Host: www.google.com\r\n"
5409 "Connection: keep-alive\r\n\r\n"),
5410 };
5411
5412 MockRead data_reads1[] = {
5413 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5414 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5415 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065416 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235417 };
5418
5419 // Resend with authorization from MyRealm's cache.
5420 MockWrite data_writes2[] = {
5421 MockWrite("GET /x/1 HTTP/1.1\r\n"
5422 "Host: www.google.com\r\n"
5423 "Connection: keep-alive\r\n"
5424 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5425 };
5426
5427 // Sever accepts the authorization.
5428 MockRead data_reads2[] = {
5429 MockRead("HTTP/1.0 200 OK\r\n"),
5430 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065431 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235432 };
5433
[email protected]31a2bfe2010-02-09 08:03:395434 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5435 data_writes1, arraysize(data_writes1));
5436 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5437 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075438 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5439 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235440
[email protected]49639fa2011-12-20 23:22:415441 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235442
[email protected]49639fa2011-12-20 23:22:415443 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425444 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235445
5446 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425447 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235448
[email protected]0757e7702009-03-27 04:00:225449 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415450 TestCompletionCallback callback2;
5451 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425452 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225453 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425454 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225455 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5456
[email protected]1c773ea12009-04-28 19:58:425457 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505458 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235459 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5460 EXPECT_EQ(100, response->headers->GetContentLength());
5461 }
5462
5463 // ------------------------------------------------------------------------
5464
5465 // Transaction 5: request a URL in MyRealm, but the server rejects the
5466 // cached identity. Should invalidate and re-prompt.
5467 {
[email protected]1c773ea12009-04-28 19:58:425468 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235469 request.method = "GET";
5470 request.url = GURL("http://www.google.com/p/q/t");
5471 request.load_flags = 0;
5472
[email protected]262eec82013-03-19 21:01:365473 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275475
[email protected]f9ee6b52008-11-08 06:46:235476 MockWrite data_writes1[] = {
5477 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5478 "Host: www.google.com\r\n"
5479 "Connection: keep-alive\r\n\r\n"),
5480 };
5481
5482 MockRead data_reads1[] = {
5483 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5484 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5485 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065486 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235487 };
5488
5489 // Resend with authorization from cache for MyRealm.
5490 MockWrite data_writes2[] = {
5491 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5492 "Host: www.google.com\r\n"
5493 "Connection: keep-alive\r\n"
5494 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5495 };
5496
5497 // Sever rejects the authorization.
5498 MockRead data_reads2[] = {
5499 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5500 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5501 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065502 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235503 };
5504
5505 // At this point we should prompt for new credentials for MyRealm.
5506 // Restart with username=foo3, password=foo4.
5507 MockWrite data_writes3[] = {
5508 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5509 "Host: www.google.com\r\n"
5510 "Connection: keep-alive\r\n"
5511 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5512 };
5513
5514 // Sever accepts the authorization.
5515 MockRead data_reads3[] = {
5516 MockRead("HTTP/1.0 200 OK\r\n"),
5517 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065518 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235519 };
5520
[email protected]31a2bfe2010-02-09 08:03:395521 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5522 data_writes1, arraysize(data_writes1));
5523 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5524 data_writes2, arraysize(data_writes2));
5525 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5526 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5528 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5529 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235530
[email protected]49639fa2011-12-20 23:22:415531 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235532
[email protected]49639fa2011-12-20 23:22:415533 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425534 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235535
5536 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425537 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235538
[email protected]0757e7702009-03-27 04:00:225539 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415540 TestCompletionCallback callback2;
5541 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425542 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225543 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425544 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225545 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5546
[email protected]1c773ea12009-04-28 19:58:425547 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505548 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045549 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235550
[email protected]49639fa2011-12-20 23:22:415551 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235552
[email protected]49639fa2011-12-20 23:22:415553 rv = trans->RestartWithAuth(
5554 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425555 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235556
[email protected]0757e7702009-03-27 04:00:225557 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425558 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235559
5560 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505561 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235562 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5563 EXPECT_EQ(100, response->headers->GetContentLength());
5564 }
5565}
[email protected]89ceba9a2009-03-21 03:46:065566
[email protected]3c32c5f2010-05-18 15:18:125567// Tests that nonce count increments when multiple auth attempts
5568// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025569TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445570 HttpAuthHandlerDigest::Factory* digest_factory =
5571 new HttpAuthHandlerDigest::Factory();
5572 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5573 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5574 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075575 session_deps_.http_auth_handler_factory.reset(digest_factory);
5576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125577
5578 // Transaction 1: authenticate (foo, bar) on MyRealm1
5579 {
[email protected]3c32c5f2010-05-18 15:18:125580 HttpRequestInfo request;
5581 request.method = "GET";
5582 request.url = GURL("http://www.google.com/x/y/z");
5583 request.load_flags = 0;
5584
[email protected]262eec82013-03-19 21:01:365585 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505586 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275587
[email protected]3c32c5f2010-05-18 15:18:125588 MockWrite data_writes1[] = {
5589 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5590 "Host: www.google.com\r\n"
5591 "Connection: keep-alive\r\n\r\n"),
5592 };
5593
5594 MockRead data_reads1[] = {
5595 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5596 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5597 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065598 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125599 };
5600
5601 // Resend with authorization (username=foo, password=bar)
5602 MockWrite data_writes2[] = {
5603 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5604 "Host: www.google.com\r\n"
5605 "Connection: keep-alive\r\n"
5606 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5607 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5608 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5609 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5610 };
5611
5612 // Sever accepts the authorization.
5613 MockRead data_reads2[] = {
5614 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065615 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125616 };
5617
5618 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5619 data_writes1, arraysize(data_writes1));
5620 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5621 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075622 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5623 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125624
[email protected]49639fa2011-12-20 23:22:415625 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125626
[email protected]49639fa2011-12-20 23:22:415627 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125628 EXPECT_EQ(ERR_IO_PENDING, rv);
5629
5630 rv = callback1.WaitForResult();
5631 EXPECT_EQ(OK, rv);
5632
5633 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505634 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045635 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125636
[email protected]49639fa2011-12-20 23:22:415637 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125638
[email protected]49639fa2011-12-20 23:22:415639 rv = trans->RestartWithAuth(
5640 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125641 EXPECT_EQ(ERR_IO_PENDING, rv);
5642
5643 rv = callback2.WaitForResult();
5644 EXPECT_EQ(OK, rv);
5645
5646 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505647 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125648 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5649 }
5650
5651 // ------------------------------------------------------------------------
5652
5653 // Transaction 2: Request another resource in digestive's protection space.
5654 // This will preemptively add an Authorization header which should have an
5655 // "nc" value of 2 (as compared to 1 in the first use.
5656 {
[email protected]3c32c5f2010-05-18 15:18:125657 HttpRequestInfo request;
5658 request.method = "GET";
5659 // Note that Transaction 1 was at /x/y/z, so this is in the same
5660 // protection space as digest.
5661 request.url = GURL("http://www.google.com/x/y/a/b");
5662 request.load_flags = 0;
5663
[email protected]262eec82013-03-19 21:01:365664 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505665 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275666
[email protected]3c32c5f2010-05-18 15:18:125667 MockWrite data_writes1[] = {
5668 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5669 "Host: www.google.com\r\n"
5670 "Connection: keep-alive\r\n"
5671 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5672 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5673 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5674 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5675 };
5676
5677 // Sever accepts the authorization.
5678 MockRead data_reads1[] = {
5679 MockRead("HTTP/1.0 200 OK\r\n"),
5680 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065681 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125682 };
5683
5684 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5685 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075686 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125687
[email protected]49639fa2011-12-20 23:22:415688 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125689
[email protected]49639fa2011-12-20 23:22:415690 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125691 EXPECT_EQ(ERR_IO_PENDING, rv);
5692
5693 rv = callback1.WaitForResult();
5694 EXPECT_EQ(OK, rv);
5695
5696 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505697 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125698 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5699 }
5700}
5701
[email protected]89ceba9a2009-03-21 03:46:065702// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025703TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065704 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075705 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405706 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065708
5709 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065710 trans->read_buf_ = new IOBuffer(15);
5711 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205712 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065713
5714 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145715 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575716 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085717 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575718 response->response_time = base::Time::Now();
5719 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065720
5721 { // Setup state for response_.vary_data
5722 HttpRequestInfo request;
5723 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5724 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275725 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435726 request.extra_headers.SetHeader("Foo", "1");
5727 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505728 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065729 }
5730
5731 // Cause the above state to be reset.
5732 trans->ResetStateForRestart();
5733
5734 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075735 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065736 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205737 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575738 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5739 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045740 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085741 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575742 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065743}
5744
[email protected]bacff652009-03-31 17:50:335745// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025746TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335747 HttpRequestInfo request;
5748 request.method = "GET";
5749 request.url = GURL("https://www.google.com/");
5750 request.load_flags = 0;
5751
[email protected]3fe8d2f82013-10-17 08:56:075752 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275753 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075754 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275755
[email protected]bacff652009-03-31 17:50:335756 MockWrite data_writes[] = {
5757 MockWrite("GET / HTTP/1.1\r\n"
5758 "Host: www.google.com\r\n"
5759 "Connection: keep-alive\r\n\r\n"),
5760 };
5761
5762 MockRead data_reads[] = {
5763 MockRead("HTTP/1.0 200 OK\r\n"),
5764 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5765 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065766 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335767 };
5768
[email protected]5ecc992a42009-11-11 01:41:595769 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395770 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5771 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065772 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5773 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335774
[email protected]bb88e1d32013-05-03 23:11:075775 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5776 session_deps_.socket_factory->AddSocketDataProvider(&data);
5777 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335779
[email protected]49639fa2011-12-20 23:22:415780 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335781
[email protected]49639fa2011-12-20 23:22:415782 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335783 EXPECT_EQ(ERR_IO_PENDING, rv);
5784
5785 rv = callback.WaitForResult();
5786 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5787
[email protected]49639fa2011-12-20 23:22:415788 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335789 EXPECT_EQ(ERR_IO_PENDING, rv);
5790
5791 rv = callback.WaitForResult();
5792 EXPECT_EQ(OK, rv);
5793
5794 const HttpResponseInfo* response = trans->GetResponseInfo();
5795
[email protected]fe2255a2011-09-20 19:37:505796 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335797 EXPECT_EQ(100, response->headers->GetContentLength());
5798}
5799
5800// Test HTTPS connections to a site with a bad certificate, going through a
5801// proxy
[email protected]23e482282013-06-14 16:08:025802TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075803 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335804
5805 HttpRequestInfo request;
5806 request.method = "GET";
5807 request.url = GURL("https://www.google.com/");
5808 request.load_flags = 0;
5809
5810 MockWrite proxy_writes[] = {
5811 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455812 "Host: www.google.com\r\n"
5813 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335814 };
5815
5816 MockRead proxy_reads[] = {
5817 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065818 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335819 };
5820
5821 MockWrite data_writes[] = {
5822 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455823 "Host: www.google.com\r\n"
5824 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335825 MockWrite("GET / HTTP/1.1\r\n"
5826 "Host: www.google.com\r\n"
5827 "Connection: keep-alive\r\n\r\n"),
5828 };
5829
5830 MockRead data_reads[] = {
5831 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5832 MockRead("HTTP/1.0 200 OK\r\n"),
5833 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5834 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065835 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335836 };
5837
[email protected]31a2bfe2010-02-09 08:03:395838 StaticSocketDataProvider ssl_bad_certificate(
5839 proxy_reads, arraysize(proxy_reads),
5840 proxy_writes, arraysize(proxy_writes));
5841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5842 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065843 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5844 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335845
[email protected]bb88e1d32013-05-03 23:11:075846 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5847 session_deps_.socket_factory->AddSocketDataProvider(&data);
5848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335850
[email protected]49639fa2011-12-20 23:22:415851 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335852
5853 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075854 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335855
[email protected]3fe8d2f82013-10-17 08:56:075856 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405857 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075858 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:335859
[email protected]49639fa2011-12-20 23:22:415860 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335861 EXPECT_EQ(ERR_IO_PENDING, rv);
5862
5863 rv = callback.WaitForResult();
5864 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5865
[email protected]49639fa2011-12-20 23:22:415866 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335867 EXPECT_EQ(ERR_IO_PENDING, rv);
5868
5869 rv = callback.WaitForResult();
5870 EXPECT_EQ(OK, rv);
5871
5872 const HttpResponseInfo* response = trans->GetResponseInfo();
5873
[email protected]fe2255a2011-09-20 19:37:505874 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335875 EXPECT_EQ(100, response->headers->GetContentLength());
5876 }
5877}
5878
[email protected]2df19bb2010-08-25 20:13:465879
5880// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025881TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075882 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205883 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5884 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075885 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465886
5887 HttpRequestInfo request;
5888 request.method = "GET";
5889 request.url = GURL("https://www.google.com/");
5890 request.load_flags = 0;
5891
5892 MockWrite data_writes[] = {
5893 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5894 "Host: www.google.com\r\n"
5895 "Proxy-Connection: keep-alive\r\n\r\n"),
5896 MockWrite("GET / HTTP/1.1\r\n"
5897 "Host: www.google.com\r\n"
5898 "Connection: keep-alive\r\n\r\n"),
5899 };
5900
5901 MockRead data_reads[] = {
5902 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5903 MockRead("HTTP/1.1 200 OK\r\n"),
5904 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5905 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065906 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465907 };
5908
5909 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5910 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065911 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5912 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465913
[email protected]bb88e1d32013-05-03 23:11:075914 session_deps_.socket_factory->AddSocketDataProvider(&data);
5915 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5916 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465917
[email protected]49639fa2011-12-20 23:22:415918 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465919
[email protected]3fe8d2f82013-10-17 08:56:075920 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465921 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:465923
[email protected]49639fa2011-12-20 23:22:415924 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465925 EXPECT_EQ(ERR_IO_PENDING, rv);
5926
5927 rv = callback.WaitForResult();
5928 EXPECT_EQ(OK, rv);
5929 const HttpResponseInfo* response = trans->GetResponseInfo();
5930
[email protected]fe2255a2011-09-20 19:37:505931 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465932
5933 EXPECT_TRUE(response->headers->IsKeepAlive());
5934 EXPECT_EQ(200, response->headers->response_code());
5935 EXPECT_EQ(100, response->headers->GetContentLength());
5936 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205937
5938 LoadTimingInfo load_timing_info;
5939 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5940 TestLoadTimingNotReusedWithPac(load_timing_info,
5941 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465942}
5943
[email protected]511f6f52010-12-17 03:58:295944// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025945TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075946 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205947 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5948 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075949 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295950
5951 HttpRequestInfo request;
5952 request.method = "GET";
5953 request.url = GURL("https://www.google.com/");
5954 request.load_flags = 0;
5955
5956 MockWrite data_writes[] = {
5957 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5958 "Host: www.google.com\r\n"
5959 "Proxy-Connection: keep-alive\r\n\r\n"),
5960 };
5961
5962 MockRead data_reads[] = {
5963 MockRead("HTTP/1.1 302 Redirect\r\n"),
5964 MockRead("Location: http://login.example.com/\r\n"),
5965 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065966 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295967 };
5968
5969 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5970 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065971 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295972
[email protected]bb88e1d32013-05-03 23:11:075973 session_deps_.socket_factory->AddSocketDataProvider(&data);
5974 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295975
[email protected]49639fa2011-12-20 23:22:415976 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295977
[email protected]3fe8d2f82013-10-17 08:56:075978 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295979 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075980 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295981
[email protected]49639fa2011-12-20 23:22:415982 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295983 EXPECT_EQ(ERR_IO_PENDING, rv);
5984
5985 rv = callback.WaitForResult();
5986 EXPECT_EQ(OK, rv);
5987 const HttpResponseInfo* response = trans->GetResponseInfo();
5988
[email protected]fe2255a2011-09-20 19:37:505989 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295990
5991 EXPECT_EQ(302, response->headers->response_code());
5992 std::string url;
5993 EXPECT_TRUE(response->headers->IsRedirect(&url));
5994 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205995
5996 // In the case of redirects from proxies, HttpNetworkTransaction returns
5997 // timing for the proxy connection instead of the connection to the host,
5998 // and no send / receive times.
5999 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6000 LoadTimingInfo load_timing_info;
6001 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6002
6003 EXPECT_FALSE(load_timing_info.socket_reused);
6004 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6005
6006 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6007 EXPECT_LE(load_timing_info.proxy_resolve_start,
6008 load_timing_info.proxy_resolve_end);
6009 EXPECT_LE(load_timing_info.proxy_resolve_end,
6010 load_timing_info.connect_timing.connect_start);
6011 ExpectConnectTimingHasTimes(
6012 load_timing_info.connect_timing,
6013 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6014
6015 EXPECT_TRUE(load_timing_info.send_start.is_null());
6016 EXPECT_TRUE(load_timing_info.send_end.is_null());
6017 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296018}
6019
6020// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026021TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076022 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296023 ProxyService::CreateFixed("https://proxy:70"));
6024
6025 HttpRequestInfo request;
6026 request.method = "GET";
6027 request.url = GURL("https://www.google.com/");
6028 request.load_flags = 0;
6029
[email protected]9075f51c2013-08-15 17:53:546030 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6031 LOWEST));
[email protected]c10b20852013-05-15 21:29:206032 scoped_ptr<SpdyFrame> goaway(
6033 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296034 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066035 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126036 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296037 };
6038
6039 static const char* const kExtraHeaders[] = {
6040 "location",
6041 "http://login.example.com/",
6042 };
[email protected]ff98d7f02012-03-22 21:44:196043 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026044 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296045 arraysize(kExtraHeaders)/2, 1));
6046 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066047 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6048 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296049 };
6050
[email protected]dd54bd82012-07-19 23:44:576051 DelayedSocketData data(
6052 1, // wait for one write to finish before reading.
6053 data_reads, arraysize(data_reads),
6054 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066055 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026056 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296057
[email protected]bb88e1d32013-05-03 23:11:076058 session_deps_.socket_factory->AddSocketDataProvider(&data);
6059 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296060
[email protected]49639fa2011-12-20 23:22:416061 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296062
[email protected]3fe8d2f82013-10-17 08:56:076063 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296064 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296066
[email protected]49639fa2011-12-20 23:22:416067 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296068 EXPECT_EQ(ERR_IO_PENDING, rv);
6069
6070 rv = callback.WaitForResult();
6071 EXPECT_EQ(OK, rv);
6072 const HttpResponseInfo* response = trans->GetResponseInfo();
6073
[email protected]fe2255a2011-09-20 19:37:506074 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296075
6076 EXPECT_EQ(302, response->headers->response_code());
6077 std::string url;
6078 EXPECT_TRUE(response->headers->IsRedirect(&url));
6079 EXPECT_EQ("http://login.example.com/", url);
6080}
6081
[email protected]4eddbc732012-08-09 05:40:176082// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026083TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176084 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076085 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296086 ProxyService::CreateFixed("https://proxy:70"));
6087
6088 HttpRequestInfo request;
6089 request.method = "GET";
6090 request.url = GURL("https://www.google.com/");
6091 request.load_flags = 0;
6092
6093 MockWrite data_writes[] = {
6094 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6095 "Host: www.google.com\r\n"
6096 "Proxy-Connection: keep-alive\r\n\r\n"),
6097 };
6098
6099 MockRead data_reads[] = {
6100 MockRead("HTTP/1.1 404 Not Found\r\n"),
6101 MockRead("Content-Length: 23\r\n\r\n"),
6102 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066103 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296104 };
6105
6106 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6107 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066108 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296109
[email protected]bb88e1d32013-05-03 23:11:076110 session_deps_.socket_factory->AddSocketDataProvider(&data);
6111 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296112
[email protected]49639fa2011-12-20 23:22:416113 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296114
[email protected]3fe8d2f82013-10-17 08:56:076115 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296116 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296118
[email protected]49639fa2011-12-20 23:22:416119 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296120 EXPECT_EQ(ERR_IO_PENDING, rv);
6121
6122 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176123 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296124
[email protected]4eddbc732012-08-09 05:40:176125 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296126}
6127
[email protected]4eddbc732012-08-09 05:40:176128// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026129TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176130 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076131 session_deps_.proxy_service.reset(
6132 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296133
6134 HttpRequestInfo request;
6135 request.method = "GET";
6136 request.url = GURL("https://www.google.com/");
6137 request.load_flags = 0;
6138
[email protected]9075f51c2013-08-15 17:53:546139 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6140 LOWEST));
[email protected]c10b20852013-05-15 21:29:206141 scoped_ptr<SpdyFrame> rst(
6142 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296143 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066144 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176145 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296146 };
6147
6148 static const char* const kExtraHeaders[] = {
6149 "location",
6150 "http://login.example.com/",
6151 };
[email protected]ff98d7f02012-03-22 21:44:196152 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026153 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296154 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196155 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026156 spdy_util_.ConstructSpdyBodyFrame(
6157 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296158 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066159 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6160 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176161 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296162 };
6163
[email protected]dd54bd82012-07-19 23:44:576164 DelayedSocketData data(
6165 1, // wait for one write to finish before reading.
6166 data_reads, arraysize(data_reads),
6167 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066168 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026169 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296170
[email protected]bb88e1d32013-05-03 23:11:076171 session_deps_.socket_factory->AddSocketDataProvider(&data);
6172 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296173
[email protected]49639fa2011-12-20 23:22:416174 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296175
[email protected]3fe8d2f82013-10-17 08:56:076176 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296177 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076178 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296179
[email protected]49639fa2011-12-20 23:22:416180 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296181 EXPECT_EQ(ERR_IO_PENDING, rv);
6182
6183 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176184 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296185
[email protected]4eddbc732012-08-09 05:40:176186 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296187}
6188
[email protected]0c5fb722012-02-28 11:50:356189// Test the request-challenge-retry sequence for basic auth, through
6190// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026191TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356192 HttpRequestInfo request;
6193 request.method = "GET";
6194 request.url = GURL("https://www.google.com/");
6195 // when the no authentication data flag is set.
6196 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6197
6198 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076199 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206200 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296201 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076202 session_deps_.net_log = log.bound().net_log();
6203 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356204
6205 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:546206 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6207 LOWEST));
[email protected]c10b20852013-05-15 21:29:206208 scoped_ptr<SpdyFrame> rst(
6209 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356210
6211 // After calling trans->RestartWithAuth(), this is the request we should
6212 // be issuing -- the final header line contains the credentials.
6213 const char* const kAuthCredentials[] = {
6214 "proxy-authorization", "Basic Zm9vOmJhcg==",
6215 };
[email protected]fba2dbde2013-05-24 16:09:016216 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:546217 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:356218 // fetch https://www.google.com/ via HTTP
6219 const char get[] = "GET / HTTP/1.1\r\n"
6220 "Host: www.google.com\r\n"
6221 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196222 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026223 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356224
6225 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206226 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216227 CreateMockWrite(*rst, 4, ASYNC),
6228 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206229 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356230 };
6231
6232 // The proxy responds to the connect with a 407, using a persistent
6233 // connection.
6234 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:026235 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
6236 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:356237 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6238 };
6239
[email protected]ff98d7f02012-03-22 21:44:196240 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:236241 spdy_util_.ConstructSpdyControlFrame(NULL,
6242 0,
6243 false,
6244 1,
6245 LOWEST,
6246 SYN_REPLY,
6247 CONTROL_FLAG_NONE,
6248 kAuthChallenge,
6249 arraysize(kAuthChallenge),
6250 0));
[email protected]0c5fb722012-02-28 11:50:356251
[email protected]23e482282013-06-14 16:08:026252 scoped_ptr<SpdyFrame> conn_resp(
6253 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356254 const char resp[] = "HTTP/1.1 200 OK\r\n"
6255 "Content-Length: 5\r\n\r\n";
6256
[email protected]ff98d7f02012-03-22 21:44:196257 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026258 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196259 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026260 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356261 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206262 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6263 CreateMockRead(*conn_resp, 6, ASYNC),
6264 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6265 CreateMockRead(*wrapped_body, 10, ASYNC),
6266 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356267 };
6268
[email protected]dd54bd82012-07-19 23:44:576269 OrderedSocketData spdy_data(
6270 spdy_reads, arraysize(spdy_reads),
6271 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076272 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356273 // Negotiate SPDY to the proxy
6274 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026275 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076276 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356277 // Vanilla SSL to the server
6278 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076279 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356280
6281 TestCompletionCallback callback1;
6282
[email protected]262eec82013-03-19 21:01:366283 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506284 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356285
6286 int rv = trans->Start(&request, callback1.callback(), log.bound());
6287 EXPECT_EQ(ERR_IO_PENDING, rv);
6288
6289 rv = callback1.WaitForResult();
6290 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576291 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356292 log.GetEntries(&entries);
6293 size_t pos = ExpectLogContainsSomewhere(
6294 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6295 NetLog::PHASE_NONE);
6296 ExpectLogContainsSomewhere(
6297 entries, pos,
6298 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6299 NetLog::PHASE_NONE);
6300
6301 const HttpResponseInfo* response = trans->GetResponseInfo();
6302 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506303 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356304 EXPECT_EQ(407, response->headers->response_code());
6305 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6306 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6307 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6308
6309 TestCompletionCallback callback2;
6310
6311 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6312 callback2.callback());
6313 EXPECT_EQ(ERR_IO_PENDING, rv);
6314
6315 rv = callback2.WaitForResult();
6316 EXPECT_EQ(OK, rv);
6317
6318 response = trans->GetResponseInfo();
6319 ASSERT_TRUE(response != NULL);
6320
6321 EXPECT_TRUE(response->headers->IsKeepAlive());
6322 EXPECT_EQ(200, response->headers->response_code());
6323 EXPECT_EQ(5, response->headers->GetContentLength());
6324 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6325
6326 // The password prompt info should not be set.
6327 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6328
[email protected]029c83b62013-01-24 05:28:206329 LoadTimingInfo load_timing_info;
6330 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6331 TestLoadTimingNotReusedWithPac(load_timing_info,
6332 CONNECT_TIMING_HAS_SSL_TIMES);
6333
[email protected]0c5fb722012-02-28 11:50:356334 trans.reset();
6335 session->CloseAllConnections();
6336}
6337
[email protected]7c6f7ba2012-04-03 04:09:296338// Test that an explicitly trusted SPDY proxy can push a resource from an
6339// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026340TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296341 HttpRequestInfo request;
6342 HttpRequestInfo push_request;
6343
[email protected]7c6f7ba2012-04-03 04:09:296344 request.method = "GET";
6345 request.url = GURL("http://www.google.com/");
6346 push_request.method = "GET";
6347 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6348
[email protected]7c6f7ba2012-04-03 04:09:296349 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076350 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206351 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296352 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076353 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506354
6355 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076356 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506357
[email protected]bb88e1d32013-05-03 23:11:076358 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296359
[email protected]cdf8f7e72013-05-23 10:56:466360 scoped_ptr<SpdyFrame> stream1_syn(
6361 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296362
6363 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466364 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296365 };
6366
6367 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026368 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296369
6370 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026371 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296372
6373 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026374 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296375 0,
6376 2,
6377 1,
6378 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436379 const char kPushedData[] = "pushed";
6380 scoped_ptr<SpdyFrame> stream2_body(
6381 spdy_util_.ConstructSpdyBodyFrame(
6382 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296383
6384 MockRead spdy_reads[] = {
6385 CreateMockRead(*stream1_reply, 2, ASYNC),
6386 CreateMockRead(*stream2_syn, 3, ASYNC),
6387 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436388 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296389 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6390 };
6391
[email protected]dd54bd82012-07-19 23:44:576392 OrderedSocketData spdy_data(
6393 spdy_reads, arraysize(spdy_reads),
6394 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076395 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296396 // Negotiate SPDY to the proxy
6397 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026398 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076399 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296400
[email protected]262eec82013-03-19 21:01:366401 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506402 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296403 TestCompletionCallback callback;
6404 int rv = trans->Start(&request, callback.callback(), log.bound());
6405 EXPECT_EQ(ERR_IO_PENDING, rv);
6406
6407 rv = callback.WaitForResult();
6408 EXPECT_EQ(OK, rv);
6409 const HttpResponseInfo* response = trans->GetResponseInfo();
6410
[email protected]262eec82013-03-19 21:01:366411 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6413 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296414 EXPECT_EQ(ERR_IO_PENDING, rv);
6415
6416 rv = callback.WaitForResult();
6417 EXPECT_EQ(OK, rv);
6418 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6419
6420 ASSERT_TRUE(response != NULL);
6421 EXPECT_TRUE(response->headers->IsKeepAlive());
6422
6423 EXPECT_EQ(200, response->headers->response_code());
6424 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6425
6426 std::string response_data;
6427 rv = ReadTransaction(trans.get(), &response_data);
6428 EXPECT_EQ(OK, rv);
6429 EXPECT_EQ("hello!", response_data);
6430
[email protected]029c83b62013-01-24 05:28:206431 LoadTimingInfo load_timing_info;
6432 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6433 TestLoadTimingNotReusedWithPac(load_timing_info,
6434 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6435
[email protected]7c6f7ba2012-04-03 04:09:296436 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506437 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296438 EXPECT_EQ(200, push_response->headers->response_code());
6439
6440 rv = ReadTransaction(push_trans.get(), &response_data);
6441 EXPECT_EQ(OK, rv);
6442 EXPECT_EQ("pushed", response_data);
6443
[email protected]029c83b62013-01-24 05:28:206444 LoadTimingInfo push_load_timing_info;
6445 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6446 TestLoadTimingReusedWithPac(push_load_timing_info);
6447 // The transactions should share a socket ID, despite being for different
6448 // origins.
6449 EXPECT_EQ(load_timing_info.socket_log_id,
6450 push_load_timing_info.socket_log_id);
6451
[email protected]7c6f7ba2012-04-03 04:09:296452 trans.reset();
6453 push_trans.reset();
6454 session->CloseAllConnections();
6455}
6456
[email protected]8c843192012-04-05 07:15:006457// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026458TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006459 HttpRequestInfo request;
6460
6461 request.method = "GET";
6462 request.url = GURL("http://www.google.com/");
6463
[email protected]8c843192012-04-05 07:15:006464 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076465 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006466 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296467 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076468 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506469
6470 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076471 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506472
[email protected]bb88e1d32013-05-03 23:11:076473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006474
[email protected]cdf8f7e72013-05-23 10:56:466475 scoped_ptr<SpdyFrame> stream1_syn(
6476 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006477
6478 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206479 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006480
6481 MockWrite spdy_writes[] = {
6482 CreateMockWrite(*stream1_syn, 1, ASYNC),
6483 CreateMockWrite(*push_rst, 4),
6484 };
6485
6486 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026487 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006488
6489 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026490 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006491
6492 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026493 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006494 0,
6495 2,
6496 1,
6497 "https://www.another-origin.com/foo.dat"));
6498
6499 MockRead spdy_reads[] = {
6500 CreateMockRead(*stream1_reply, 2, ASYNC),
6501 CreateMockRead(*stream2_syn, 3, ASYNC),
6502 CreateMockRead(*stream1_body, 5, ASYNC),
6503 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6504 };
6505
[email protected]dd54bd82012-07-19 23:44:576506 OrderedSocketData spdy_data(
6507 spdy_reads, arraysize(spdy_reads),
6508 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076509 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006510 // Negotiate SPDY to the proxy
6511 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026512 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076513 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006514
[email protected]262eec82013-03-19 21:01:366515 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506516 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006517 TestCompletionCallback callback;
6518 int rv = trans->Start(&request, callback.callback(), log.bound());
6519 EXPECT_EQ(ERR_IO_PENDING, rv);
6520
6521 rv = callback.WaitForResult();
6522 EXPECT_EQ(OK, rv);
6523 const HttpResponseInfo* response = trans->GetResponseInfo();
6524
6525 ASSERT_TRUE(response != NULL);
6526 EXPECT_TRUE(response->headers->IsKeepAlive());
6527
6528 EXPECT_EQ(200, response->headers->response_code());
6529 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6530
6531 std::string response_data;
6532 rv = ReadTransaction(trans.get(), &response_data);
6533 EXPECT_EQ(OK, rv);
6534 EXPECT_EQ("hello!", response_data);
6535
6536 trans.reset();
6537 session->CloseAllConnections();
6538}
6539
[email protected]2df19bb2010-08-25 20:13:466540// Test HTTPS connections to a site with a bad certificate, going through an
6541// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026542TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076543 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116544 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466545
6546 HttpRequestInfo request;
6547 request.method = "GET";
6548 request.url = GURL("https://www.google.com/");
6549 request.load_flags = 0;
6550
6551 // Attempt to fetch the URL from a server with a bad cert
6552 MockWrite bad_cert_writes[] = {
6553 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6554 "Host: www.google.com\r\n"
6555 "Proxy-Connection: keep-alive\r\n\r\n"),
6556 };
6557
6558 MockRead bad_cert_reads[] = {
6559 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066560 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466561 };
6562
6563 // Attempt to fetch the URL with a good cert
6564 MockWrite good_data_writes[] = {
6565 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6566 "Host: www.google.com\r\n"
6567 "Proxy-Connection: keep-alive\r\n\r\n"),
6568 MockWrite("GET / HTTP/1.1\r\n"
6569 "Host: www.google.com\r\n"
6570 "Connection: keep-alive\r\n\r\n"),
6571 };
6572
6573 MockRead good_cert_reads[] = {
6574 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6575 MockRead("HTTP/1.0 200 OK\r\n"),
6576 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6577 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066578 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466579 };
6580
6581 StaticSocketDataProvider ssl_bad_certificate(
6582 bad_cert_reads, arraysize(bad_cert_reads),
6583 bad_cert_writes, arraysize(bad_cert_writes));
6584 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6585 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066586 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6587 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466588
6589 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6591 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466593
6594 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6596 session_deps_.socket_factory->AddSocketDataProvider(&data);
6597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466598
[email protected]49639fa2011-12-20 23:22:416599 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466600
[email protected]3fe8d2f82013-10-17 08:56:076601 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466602 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076603 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466604
[email protected]49639fa2011-12-20 23:22:416605 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466606 EXPECT_EQ(ERR_IO_PENDING, rv);
6607
6608 rv = callback.WaitForResult();
6609 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6610
[email protected]49639fa2011-12-20 23:22:416611 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466612 EXPECT_EQ(ERR_IO_PENDING, rv);
6613
6614 rv = callback.WaitForResult();
6615 EXPECT_EQ(OK, rv);
6616
6617 const HttpResponseInfo* response = trans->GetResponseInfo();
6618
[email protected]fe2255a2011-09-20 19:37:506619 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466620 EXPECT_EQ(100, response->headers->GetContentLength());
6621}
6622
[email protected]23e482282013-06-14 16:08:026623TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426624 HttpRequestInfo request;
6625 request.method = "GET";
6626 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436627 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6628 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426629
[email protected]3fe8d2f82013-10-17 08:56:076630 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276631 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076632 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276633
[email protected]1c773ea12009-04-28 19:58:426634 MockWrite data_writes[] = {
6635 MockWrite("GET / HTTP/1.1\r\n"
6636 "Host: www.google.com\r\n"
6637 "Connection: keep-alive\r\n"
6638 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6639 };
6640
6641 // Lastly, the server responds with the actual content.
6642 MockRead data_reads[] = {
6643 MockRead("HTTP/1.0 200 OK\r\n"),
6644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6645 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066646 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426647 };
6648
[email protected]31a2bfe2010-02-09 08:03:396649 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6650 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076651 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426652
[email protected]49639fa2011-12-20 23:22:416653 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426654
[email protected]49639fa2011-12-20 23:22:416655 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426656 EXPECT_EQ(ERR_IO_PENDING, rv);
6657
6658 rv = callback.WaitForResult();
6659 EXPECT_EQ(OK, rv);
6660}
6661
[email protected]23e482282013-06-14 16:08:026662TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296663 HttpRequestInfo request;
6664 request.method = "GET";
6665 request.url = GURL("https://www.google.com/");
6666 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6667 "Chromium Ultra Awesome X Edition");
6668
[email protected]bb88e1d32013-05-03 23:11:076669 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076670 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276671 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076672 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276673
[email protected]da81f132010-08-18 23:39:296674 MockWrite data_writes[] = {
6675 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6676 "Host: www.google.com\r\n"
6677 "Proxy-Connection: keep-alive\r\n"
6678 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6679 };
6680 MockRead data_reads[] = {
6681 // Return an error, so the transaction stops here (this test isn't
6682 // interested in the rest).
6683 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6684 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6685 MockRead("Proxy-Connection: close\r\n\r\n"),
6686 };
6687
6688 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6689 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076690 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296691
[email protected]49639fa2011-12-20 23:22:416692 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296693
[email protected]49639fa2011-12-20 23:22:416694 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296695 EXPECT_EQ(ERR_IO_PENDING, rv);
6696
6697 rv = callback.WaitForResult();
6698 EXPECT_EQ(OK, rv);
6699}
6700
[email protected]23e482282013-06-14 16:08:026701TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426702 HttpRequestInfo request;
6703 request.method = "GET";
6704 request.url = GURL("http://www.google.com/");
6705 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166706 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6707 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426708
[email protected]3fe8d2f82013-10-17 08:56:076709 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276710 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076711 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276712
[email protected]1c773ea12009-04-28 19:58:426713 MockWrite data_writes[] = {
6714 MockWrite("GET / HTTP/1.1\r\n"
6715 "Host: www.google.com\r\n"
6716 "Connection: keep-alive\r\n"
6717 "Referer: http://the.previous.site.com/\r\n\r\n"),
6718 };
6719
6720 // Lastly, the server responds with the actual content.
6721 MockRead data_reads[] = {
6722 MockRead("HTTP/1.0 200 OK\r\n"),
6723 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6724 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066725 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426726 };
6727
[email protected]31a2bfe2010-02-09 08:03:396728 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6729 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076730 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426731
[email protected]49639fa2011-12-20 23:22:416732 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426733
[email protected]49639fa2011-12-20 23:22:416734 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426735 EXPECT_EQ(ERR_IO_PENDING, rv);
6736
6737 rv = callback.WaitForResult();
6738 EXPECT_EQ(OK, rv);
6739}
6740
[email protected]23e482282013-06-14 16:08:026741TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426742 HttpRequestInfo request;
6743 request.method = "POST";
6744 request.url = GURL("http://www.google.com/");
6745
[email protected]3fe8d2f82013-10-17 08:56:076746 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276747 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076748 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276749
[email protected]1c773ea12009-04-28 19:58:426750 MockWrite data_writes[] = {
6751 MockWrite("POST / HTTP/1.1\r\n"
6752 "Host: www.google.com\r\n"
6753 "Connection: keep-alive\r\n"
6754 "Content-Length: 0\r\n\r\n"),
6755 };
6756
6757 // Lastly, the server responds with the actual content.
6758 MockRead data_reads[] = {
6759 MockRead("HTTP/1.0 200 OK\r\n"),
6760 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6761 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066762 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426763 };
6764
[email protected]31a2bfe2010-02-09 08:03:396765 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6766 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076767 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426768
[email protected]49639fa2011-12-20 23:22:416769 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426770
[email protected]49639fa2011-12-20 23:22:416771 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426772 EXPECT_EQ(ERR_IO_PENDING, rv);
6773
6774 rv = callback.WaitForResult();
6775 EXPECT_EQ(OK, rv);
6776}
6777
[email protected]23e482282013-06-14 16:08:026778TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426779 HttpRequestInfo request;
6780 request.method = "PUT";
6781 request.url = GURL("http://www.google.com/");
6782
[email protected]3fe8d2f82013-10-17 08:56:076783 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276784 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276786
[email protected]1c773ea12009-04-28 19:58:426787 MockWrite data_writes[] = {
6788 MockWrite("PUT / HTTP/1.1\r\n"
6789 "Host: www.google.com\r\n"
6790 "Connection: keep-alive\r\n"
6791 "Content-Length: 0\r\n\r\n"),
6792 };
6793
6794 // Lastly, the server responds with the actual content.
6795 MockRead data_reads[] = {
6796 MockRead("HTTP/1.0 200 OK\r\n"),
6797 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6798 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066799 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426800 };
6801
[email protected]31a2bfe2010-02-09 08:03:396802 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6803 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076804 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426805
[email protected]49639fa2011-12-20 23:22:416806 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426807
[email protected]49639fa2011-12-20 23:22:416808 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426809 EXPECT_EQ(ERR_IO_PENDING, rv);
6810
6811 rv = callback.WaitForResult();
6812 EXPECT_EQ(OK, rv);
6813}
6814
[email protected]23e482282013-06-14 16:08:026815TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426816 HttpRequestInfo request;
6817 request.method = "HEAD";
6818 request.url = GURL("http://www.google.com/");
6819
[email protected]3fe8d2f82013-10-17 08:56:076820 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276821 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076822 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276823
[email protected]1c773ea12009-04-28 19:58:426824 MockWrite data_writes[] = {
6825 MockWrite("HEAD / HTTP/1.1\r\n"
6826 "Host: www.google.com\r\n"
6827 "Connection: keep-alive\r\n"
6828 "Content-Length: 0\r\n\r\n"),
6829 };
6830
6831 // Lastly, the server responds with the actual content.
6832 MockRead data_reads[] = {
6833 MockRead("HTTP/1.0 200 OK\r\n"),
6834 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6835 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066836 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426837 };
6838
[email protected]31a2bfe2010-02-09 08:03:396839 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6840 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076841 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426842
[email protected]49639fa2011-12-20 23:22:416843 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426844
[email protected]49639fa2011-12-20 23:22:416845 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426846 EXPECT_EQ(ERR_IO_PENDING, rv);
6847
6848 rv = callback.WaitForResult();
6849 EXPECT_EQ(OK, rv);
6850}
6851
[email protected]23e482282013-06-14 16:08:026852TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426853 HttpRequestInfo request;
6854 request.method = "GET";
6855 request.url = GURL("http://www.google.com/");
6856 request.load_flags = LOAD_BYPASS_CACHE;
6857
[email protected]3fe8d2f82013-10-17 08:56:076858 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276859 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076860 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276861
[email protected]1c773ea12009-04-28 19:58:426862 MockWrite data_writes[] = {
6863 MockWrite("GET / HTTP/1.1\r\n"
6864 "Host: www.google.com\r\n"
6865 "Connection: keep-alive\r\n"
6866 "Pragma: no-cache\r\n"
6867 "Cache-Control: no-cache\r\n\r\n"),
6868 };
6869
6870 // Lastly, the server responds with the actual content.
6871 MockRead data_reads[] = {
6872 MockRead("HTTP/1.0 200 OK\r\n"),
6873 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6874 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066875 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426876 };
6877
[email protected]31a2bfe2010-02-09 08:03:396878 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6879 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076880 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426881
[email protected]49639fa2011-12-20 23:22:416882 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426883
[email protected]49639fa2011-12-20 23:22:416884 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426885 EXPECT_EQ(ERR_IO_PENDING, rv);
6886
6887 rv = callback.WaitForResult();
6888 EXPECT_EQ(OK, rv);
6889}
6890
[email protected]23e482282013-06-14 16:08:026891TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426892 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426893 HttpRequestInfo request;
6894 request.method = "GET";
6895 request.url = GURL("http://www.google.com/");
6896 request.load_flags = LOAD_VALIDATE_CACHE;
6897
[email protected]3fe8d2f82013-10-17 08:56:076898 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276899 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276901
[email protected]1c773ea12009-04-28 19:58:426902 MockWrite data_writes[] = {
6903 MockWrite("GET / HTTP/1.1\r\n"
6904 "Host: www.google.com\r\n"
6905 "Connection: keep-alive\r\n"
6906 "Cache-Control: max-age=0\r\n\r\n"),
6907 };
6908
6909 // Lastly, the server responds with the actual content.
6910 MockRead data_reads[] = {
6911 MockRead("HTTP/1.0 200 OK\r\n"),
6912 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6913 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066914 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426915 };
6916
[email protected]31a2bfe2010-02-09 08:03:396917 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6918 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076919 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426920
[email protected]49639fa2011-12-20 23:22:416921 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426922
[email protected]49639fa2011-12-20 23:22:416923 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426924 EXPECT_EQ(ERR_IO_PENDING, rv);
6925
6926 rv = callback.WaitForResult();
6927 EXPECT_EQ(OK, rv);
6928}
6929
[email protected]23e482282013-06-14 16:08:026930TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426931 HttpRequestInfo request;
6932 request.method = "GET";
6933 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436934 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426935
[email protected]3fe8d2f82013-10-17 08:56:076936 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276937 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276939
[email protected]1c773ea12009-04-28 19:58:426940 MockWrite data_writes[] = {
6941 MockWrite("GET / HTTP/1.1\r\n"
6942 "Host: www.google.com\r\n"
6943 "Connection: keep-alive\r\n"
6944 "FooHeader: Bar\r\n\r\n"),
6945 };
6946
6947 // Lastly, the server responds with the actual content.
6948 MockRead data_reads[] = {
6949 MockRead("HTTP/1.0 200 OK\r\n"),
6950 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6951 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066952 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426953 };
6954
[email protected]31a2bfe2010-02-09 08:03:396955 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6956 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076957 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426958
[email protected]49639fa2011-12-20 23:22:416959 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426960
[email protected]49639fa2011-12-20 23:22:416961 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426962 EXPECT_EQ(ERR_IO_PENDING, rv);
6963
6964 rv = callback.WaitForResult();
6965 EXPECT_EQ(OK, rv);
6966}
6967
[email protected]23e482282013-06-14 16:08:026968TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476969 HttpRequestInfo request;
6970 request.method = "GET";
6971 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436972 request.extra_headers.SetHeader("referer", "www.foo.com");
6973 request.extra_headers.SetHeader("hEllo", "Kitty");
6974 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476975
[email protected]3fe8d2f82013-10-17 08:56:076976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276977 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276979
[email protected]270c6412010-03-29 22:02:476980 MockWrite data_writes[] = {
6981 MockWrite("GET / HTTP/1.1\r\n"
6982 "Host: www.google.com\r\n"
6983 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166984 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476985 "hEllo: Kitty\r\n"
6986 "FoO: bar\r\n\r\n"),
6987 };
6988
6989 // Lastly, the server responds with the actual content.
6990 MockRead data_reads[] = {
6991 MockRead("HTTP/1.0 200 OK\r\n"),
6992 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6993 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066994 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476995 };
6996
6997 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6998 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076999 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477000
[email protected]49639fa2011-12-20 23:22:417001 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477002
[email protected]49639fa2011-12-20 23:22:417003 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477004 EXPECT_EQ(ERR_IO_PENDING, rv);
7005
7006 rv = callback.WaitForResult();
7007 EXPECT_EQ(OK, rv);
7008}
7009
[email protected]23e482282013-06-14 16:08:027010TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277011 HttpRequestInfo request;
7012 request.method = "GET";
7013 request.url = GURL("http://www.google.com/");
7014 request.load_flags = 0;
7015
[email protected]bb88e1d32013-05-03 23:11:077016 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207017 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7018 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077019 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027020
[email protected]3fe8d2f82013-10-17 08:56:077021 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027022 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027024
[email protected]3cd17242009-06-23 02:59:027025 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7026 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7027
7028 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067029 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027030 MockWrite("GET / HTTP/1.1\r\n"
7031 "Host: www.google.com\r\n"
7032 "Connection: keep-alive\r\n\r\n")
7033 };
7034
7035 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067036 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027037 MockRead("HTTP/1.0 200 OK\r\n"),
7038 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7039 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067040 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027041 };
7042
[email protected]31a2bfe2010-02-09 08:03:397043 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7044 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077045 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027046
[email protected]49639fa2011-12-20 23:22:417047 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027048
[email protected]49639fa2011-12-20 23:22:417049 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027050 EXPECT_EQ(ERR_IO_PENDING, rv);
7051
7052 rv = callback.WaitForResult();
7053 EXPECT_EQ(OK, rv);
7054
7055 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507056 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027057
[email protected]029c83b62013-01-24 05:28:207058 LoadTimingInfo load_timing_info;
7059 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7060 TestLoadTimingNotReusedWithPac(load_timing_info,
7061 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7062
[email protected]3cd17242009-06-23 02:59:027063 std::string response_text;
7064 rv = ReadTransaction(trans.get(), &response_text);
7065 EXPECT_EQ(OK, rv);
7066 EXPECT_EQ("Payload", response_text);
7067}
7068
[email protected]23e482282013-06-14 16:08:027069TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277070 HttpRequestInfo request;
7071 request.method = "GET";
7072 request.url = GURL("https://www.google.com/");
7073 request.load_flags = 0;
7074
[email protected]bb88e1d32013-05-03 23:11:077075 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207076 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7077 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077078 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027079
[email protected]3fe8d2f82013-10-17 08:56:077080 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027081 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077082 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:027083
[email protected]3cd17242009-06-23 02:59:027084 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7085 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7086
7087 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067088 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357089 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027090 MockWrite("GET / HTTP/1.1\r\n"
7091 "Host: www.google.com\r\n"
7092 "Connection: keep-alive\r\n\r\n")
7093 };
7094
7095 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017096 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7097 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357098 MockRead("HTTP/1.0 200 OK\r\n"),
7099 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7100 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067101 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357102 };
7103
[email protected]31a2bfe2010-02-09 08:03:397104 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7105 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077106 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357107
[email protected]8ddf8322012-02-23 18:08:067108 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077109 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357110
[email protected]49639fa2011-12-20 23:22:417111 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357112
[email protected]49639fa2011-12-20 23:22:417113 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357114 EXPECT_EQ(ERR_IO_PENDING, rv);
7115
7116 rv = callback.WaitForResult();
7117 EXPECT_EQ(OK, rv);
7118
[email protected]029c83b62013-01-24 05:28:207119 LoadTimingInfo load_timing_info;
7120 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7121 TestLoadTimingNotReusedWithPac(load_timing_info,
7122 CONNECT_TIMING_HAS_SSL_TIMES);
7123
[email protected]e0c27be2009-07-15 13:09:357124 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507125 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357126
7127 std::string response_text;
7128 rv = ReadTransaction(trans.get(), &response_text);
7129 EXPECT_EQ(OK, rv);
7130 EXPECT_EQ("Payload", response_text);
7131}
7132
[email protected]23e482282013-06-14 16:08:027133TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207134 HttpRequestInfo request;
7135 request.method = "GET";
7136 request.url = GURL("http://www.google.com/");
7137 request.load_flags = 0;
7138
[email protected]bb88e1d32013-05-03 23:11:077139 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207140 ProxyService::CreateFixed("socks4://myproxy:1080"));
7141 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077142 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207143
[email protected]3fe8d2f82013-10-17 08:56:077144 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207145 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077146 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:207147
7148 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7149 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7150
7151 MockWrite data_writes[] = {
7152 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7153 MockWrite("GET / HTTP/1.1\r\n"
7154 "Host: www.google.com\r\n"
7155 "Connection: keep-alive\r\n\r\n")
7156 };
7157
7158 MockRead data_reads[] = {
7159 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7160 MockRead("HTTP/1.0 200 OK\r\n"),
7161 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7162 MockRead("Payload"),
7163 MockRead(SYNCHRONOUS, OK)
7164 };
7165
7166 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7167 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077168 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207169
7170 TestCompletionCallback callback;
7171
7172 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7173 EXPECT_EQ(ERR_IO_PENDING, rv);
7174
7175 rv = callback.WaitForResult();
7176 EXPECT_EQ(OK, rv);
7177
7178 const HttpResponseInfo* response = trans->GetResponseInfo();
7179 ASSERT_TRUE(response != NULL);
7180
7181 LoadTimingInfo load_timing_info;
7182 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7183 TestLoadTimingNotReused(load_timing_info,
7184 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7185
7186 std::string response_text;
7187 rv = ReadTransaction(trans.get(), &response_text);
7188 EXPECT_EQ(OK, rv);
7189 EXPECT_EQ("Payload", response_text);
7190}
7191
[email protected]23e482282013-06-14 16:08:027192TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277193 HttpRequestInfo request;
7194 request.method = "GET";
7195 request.url = GURL("http://www.google.com/");
7196 request.load_flags = 0;
7197
[email protected]bb88e1d32013-05-03 23:11:077198 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207199 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7200 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077201 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357202
[email protected]3fe8d2f82013-10-17 08:56:077203 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357204 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077205 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357206
[email protected]e0c27be2009-07-15 13:09:357207 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7208 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377209 const char kSOCKS5OkRequest[] = {
7210 0x05, // Version
7211 0x01, // Command (CONNECT)
7212 0x00, // Reserved.
7213 0x03, // Address type (DOMAINNAME).
7214 0x0E, // Length of domain (14)
7215 // Domain string:
7216 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7217 0x00, 0x50, // 16-bit port (80)
7218 };
[email protected]e0c27be2009-07-15 13:09:357219 const char kSOCKS5OkResponse[] =
7220 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7221
7222 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067223 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7224 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357225 MockWrite("GET / HTTP/1.1\r\n"
7226 "Host: www.google.com\r\n"
7227 "Connection: keep-alive\r\n\r\n")
7228 };
7229
7230 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017231 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7232 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357233 MockRead("HTTP/1.0 200 OK\r\n"),
7234 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7235 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067236 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357237 };
7238
[email protected]31a2bfe2010-02-09 08:03:397239 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7240 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077241 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357242
[email protected]49639fa2011-12-20 23:22:417243 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357244
[email protected]49639fa2011-12-20 23:22:417245 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357246 EXPECT_EQ(ERR_IO_PENDING, rv);
7247
7248 rv = callback.WaitForResult();
7249 EXPECT_EQ(OK, rv);
7250
7251 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507252 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357253
[email protected]029c83b62013-01-24 05:28:207254 LoadTimingInfo load_timing_info;
7255 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7256 TestLoadTimingNotReusedWithPac(load_timing_info,
7257 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7258
[email protected]e0c27be2009-07-15 13:09:357259 std::string response_text;
7260 rv = ReadTransaction(trans.get(), &response_text);
7261 EXPECT_EQ(OK, rv);
7262 EXPECT_EQ("Payload", response_text);
7263}
7264
[email protected]23e482282013-06-14 16:08:027265TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277266 HttpRequestInfo request;
7267 request.method = "GET";
7268 request.url = GURL("https://www.google.com/");
7269 request.load_flags = 0;
7270
[email protected]bb88e1d32013-05-03 23:11:077271 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207272 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7273 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077274 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357275
[email protected]3fe8d2f82013-10-17 08:56:077276 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357277 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357279
[email protected]e0c27be2009-07-15 13:09:357280 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7281 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377282 const unsigned char kSOCKS5OkRequest[] = {
7283 0x05, // Version
7284 0x01, // Command (CONNECT)
7285 0x00, // Reserved.
7286 0x03, // Address type (DOMAINNAME).
7287 0x0E, // Length of domain (14)
7288 // Domain string:
7289 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7290 0x01, 0xBB, // 16-bit port (443)
7291 };
7292
[email protected]e0c27be2009-07-15 13:09:357293 const char kSOCKS5OkResponse[] =
7294 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7295
7296 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067297 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7298 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357299 arraysize(kSOCKS5OkRequest)),
7300 MockWrite("GET / HTTP/1.1\r\n"
7301 "Host: www.google.com\r\n"
7302 "Connection: keep-alive\r\n\r\n")
7303 };
7304
7305 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017306 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7307 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027308 MockRead("HTTP/1.0 200 OK\r\n"),
7309 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7310 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067311 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027312 };
7313
[email protected]31a2bfe2010-02-09 08:03:397314 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7315 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077316 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027317
[email protected]8ddf8322012-02-23 18:08:067318 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077319 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027320
[email protected]49639fa2011-12-20 23:22:417321 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027322
[email protected]49639fa2011-12-20 23:22:417323 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027324 EXPECT_EQ(ERR_IO_PENDING, rv);
7325
7326 rv = callback.WaitForResult();
7327 EXPECT_EQ(OK, rv);
7328
7329 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507330 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027331
[email protected]029c83b62013-01-24 05:28:207332 LoadTimingInfo load_timing_info;
7333 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7334 TestLoadTimingNotReusedWithPac(load_timing_info,
7335 CONNECT_TIMING_HAS_SSL_TIMES);
7336
[email protected]3cd17242009-06-23 02:59:027337 std::string response_text;
7338 rv = ReadTransaction(trans.get(), &response_text);
7339 EXPECT_EQ(OK, rv);
7340 EXPECT_EQ("Payload", response_text);
7341}
7342
[email protected]448d4ca52012-03-04 04:12:237343namespace {
7344
[email protected]04e5be32009-06-26 20:00:317345// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067346
7347struct GroupNameTest {
7348 std::string proxy_server;
7349 std::string url;
7350 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187351 bool ssl;
[email protected]2d731a32010-04-29 01:04:067352};
7353
7354scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437355 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077356 SpdySessionDependencies* session_deps_) {
7357 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067358
[email protected]30d4c022013-07-18 22:58:167359 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537360 session->http_server_properties();
7361 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067362 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437363 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067364
7365 return session;
7366}
7367
7368int GroupNameTransactionHelper(
7369 const std::string& url,
7370 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067371 HttpRequestInfo request;
7372 request.method = "GET";
7373 request.url = GURL(url);
7374 request.load_flags = 0;
7375
[email protected]262eec82013-03-19 21:01:367376 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277378
[email protected]49639fa2011-12-20 23:22:417379 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067380
7381 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417382 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067383}
7384
[email protected]448d4ca52012-03-04 04:12:237385} // namespace
7386
[email protected]23e482282013-06-14 16:08:027387TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067388 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317389 {
[email protected]2d731a32010-04-29 01:04:067390 "", // unused
[email protected]04e5be32009-06-26 20:00:317391 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547392 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187393 false,
[email protected]2ff8b312010-04-26 22:20:547394 },
7395 {
[email protected]2d731a32010-04-29 01:04:067396 "", // unused
[email protected]2ff8b312010-04-26 22:20:547397 "http://[2001:1418:13:1::25]/direct",
7398 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187399 false,
[email protected]04e5be32009-06-26 20:00:317400 },
[email protected]04e5be32009-06-26 20:00:317401
7402 // SSL Tests
7403 {
[email protected]2d731a32010-04-29 01:04:067404 "", // unused
[email protected]04e5be32009-06-26 20:00:317405 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027406 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187407 true,
[email protected]04e5be32009-06-26 20:00:317408 },
7409 {
[email protected]2d731a32010-04-29 01:04:067410 "", // unused
7411 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027412 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187413 true,
[email protected]04e5be32009-06-26 20:00:317414 },
7415 {
[email protected]2d731a32010-04-29 01:04:067416 "", // unused
[email protected]2ff8b312010-04-26 22:20:547417 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027418 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187419 true,
[email protected]2ff8b312010-04-26 22:20:547420 },
[email protected]2d731a32010-04-29 01:04:067421 };
[email protected]2ff8b312010-04-26 22:20:547422
[email protected]8e6441ca2010-08-19 05:56:387423 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067424
7425 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077426 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027427 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067428 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437429 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067430
7431 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287432 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7433 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137434 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347435 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447436 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7437 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027438 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7439 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447440 peer.SetClientSocketPoolManager(
7441 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067442
7443 EXPECT_EQ(ERR_IO_PENDING,
7444 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187445 if (tests[i].ssl)
7446 EXPECT_EQ(tests[i].expected_group_name,
7447 ssl_conn_pool->last_group_name_received());
7448 else
7449 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287450 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067451 }
7452
[email protected]2d731a32010-04-29 01:04:067453}
7454
[email protected]23e482282013-06-14 16:08:027455TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067456 const GroupNameTest tests[] = {
7457 {
7458 "http_proxy",
7459 "http://www.google.com/http_proxy_normal",
7460 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187461 false,
[email protected]2d731a32010-04-29 01:04:067462 },
7463
7464 // SSL Tests
7465 {
7466 "http_proxy",
7467 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027468 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187469 true,
[email protected]2d731a32010-04-29 01:04:067470 },
[email protected]af3490e2010-10-16 21:02:297471
[email protected]9faeded92010-04-29 20:03:057472 {
7473 "http_proxy",
7474 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027475 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187476 true,
[email protected]9faeded92010-04-29 20:03:057477 },
[email protected]45499252013-01-23 17:12:567478
7479 {
7480 "http_proxy",
7481 "ftp://ftp.google.com/http_proxy_normal",
7482 "ftp/ftp.google.com:21",
7483 false,
7484 },
[email protected]2d731a32010-04-29 01:04:067485 };
7486
[email protected]8e6441ca2010-08-19 05:56:387487 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067488
7489 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077490 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027491 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067492 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437493 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067494
7495 HttpNetworkSessionPeer peer(session);
7496
[email protected]e60e47a2010-07-14 03:37:187497 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137498 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347499 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137500 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347501 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027502
[email protected]831e4a32013-11-14 02:14:447503 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7504 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027505 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7506 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447507 peer.SetClientSocketPoolManager(
7508 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067509
7510 EXPECT_EQ(ERR_IO_PENDING,
7511 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187512 if (tests[i].ssl)
7513 EXPECT_EQ(tests[i].expected_group_name,
7514 ssl_conn_pool->last_group_name_received());
7515 else
7516 EXPECT_EQ(tests[i].expected_group_name,
7517 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067518 }
[email protected]2d731a32010-04-29 01:04:067519}
7520
[email protected]23e482282013-06-14 16:08:027521TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067522 const GroupNameTest tests[] = {
7523 {
7524 "socks4://socks_proxy:1080",
7525 "http://www.google.com/socks4_direct",
7526 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187527 false,
[email protected]2d731a32010-04-29 01:04:067528 },
7529 {
7530 "socks5://socks_proxy:1080",
7531 "http://www.google.com/socks5_direct",
7532 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187533 false,
[email protected]2d731a32010-04-29 01:04:067534 },
7535
7536 // SSL Tests
7537 {
7538 "socks4://socks_proxy:1080",
7539 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027540 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187541 true,
[email protected]2d731a32010-04-29 01:04:067542 },
7543 {
7544 "socks5://socks_proxy:1080",
7545 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027546 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187547 true,
[email protected]2d731a32010-04-29 01:04:067548 },
[email protected]af3490e2010-10-16 21:02:297549
[email protected]9faeded92010-04-29 20:03:057550 {
7551 "socks4://socks_proxy:1080",
7552 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027553 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187554 true,
[email protected]9faeded92010-04-29 20:03:057555 },
[email protected]04e5be32009-06-26 20:00:317556 };
7557
[email protected]8e6441ca2010-08-19 05:56:387558 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547559
[email protected]04e5be32009-06-26 20:00:317560 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077561 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027562 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067563 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437564 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027565
[email protected]2d731a32010-04-29 01:04:067566 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317567
[email protected]e60e47a2010-07-14 03:37:187568 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137569 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347570 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137571 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347572 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027573
[email protected]831e4a32013-11-14 02:14:447574 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7575 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027576 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7577 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447578 peer.SetClientSocketPoolManager(
7579 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317580
[email protected]262eec82013-03-19 21:01:367581 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317583
[email protected]2d731a32010-04-29 01:04:067584 EXPECT_EQ(ERR_IO_PENDING,
7585 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187586 if (tests[i].ssl)
7587 EXPECT_EQ(tests[i].expected_group_name,
7588 ssl_conn_pool->last_group_name_received());
7589 else
7590 EXPECT_EQ(tests[i].expected_group_name,
7591 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317592 }
7593}
7594
[email protected]23e482282013-06-14 16:08:027595TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277596 HttpRequestInfo request;
7597 request.method = "GET";
7598 request.url = GURL("http://www.google.com/");
7599
[email protected]bb88e1d32013-05-03 23:11:077600 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007601 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327602
[email protected]69719062010-01-05 20:09:217603 // This simulates failure resolving all hostnames; that means we will fail
7604 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077605 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327606
[email protected]3fe8d2f82013-10-17 08:56:077607 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257608 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257610
[email protected]49639fa2011-12-20 23:22:417611 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257612
[email protected]49639fa2011-12-20 23:22:417613 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257614 EXPECT_EQ(ERR_IO_PENDING, rv);
7615
[email protected]9172a982009-06-06 00:30:257616 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017617 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257618}
7619
[email protected]685af592010-05-11 19:31:247620// Base test to make sure that when the load flags for a request specify to
7621// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027622void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077623 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277624 // Issue a request, asking to bypass the cache(s).
7625 HttpRequestInfo request;
7626 request.method = "GET";
7627 request.load_flags = load_flags;
7628 request.url = GURL("http://www.google.com/");
7629
[email protected]a2c2fb92009-07-18 07:31:047630 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077631 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327632
[email protected]3fe8d2f82013-10-17 08:56:077633 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7634 scoped_ptr<HttpTransaction> trans(
7635 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287636
[email protected]6e78dfb2011-07-28 21:34:477637 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287638 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297639 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077640 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107641 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7642 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417643 &addrlist,
7644 callback.callback(),
7645 NULL,
7646 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477647 EXPECT_EQ(ERR_IO_PENDING, rv);
7648 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287649 EXPECT_EQ(OK, rv);
7650
7651 // Verify that it was added to host cache, by doing a subsequent async lookup
7652 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077653 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107654 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7655 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417656 &addrlist,
7657 callback.callback(),
7658 NULL,
7659 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327660 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287661
7662 // Inject a failure the next time that "www.google.com" is resolved. This way
7663 // we can tell if the next lookup hit the cache, or the "network".
7664 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077665 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287666
7667 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7668 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067669 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397670 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077671 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287672
[email protected]3b9cca42009-06-16 01:08:287673 // Run the request.
[email protected]49639fa2011-12-20 23:22:417674 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287675 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417676 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287677
7678 // If we bypassed the cache, we would have gotten a failure while resolving
7679 // "www.google.com".
7680 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7681}
7682
[email protected]685af592010-05-11 19:31:247683// There are multiple load flags that should trigger the host cache bypass.
7684// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027685TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247686 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7687}
7688
[email protected]23e482282013-06-14 16:08:027689TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247690 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7691}
7692
[email protected]23e482282013-06-14 16:08:027693TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247694 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7695}
7696
[email protected]0877e3d2009-10-17 22:29:577697// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027698TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577699 HttpRequestInfo request;
7700 request.method = "GET";
7701 request.url = GURL("http://www.foo.com/");
7702 request.load_flags = 0;
7703
7704 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067705 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577706 };
[email protected]31a2bfe2010-02-09 08:03:397707 StaticSocketDataProvider data(NULL, 0,
7708 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077709 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077710 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577711
[email protected]49639fa2011-12-20 23:22:417712 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577713
7714 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577716
[email protected]49639fa2011-12-20 23:22:417717 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577718 EXPECT_EQ(ERR_IO_PENDING, rv);
7719
7720 rv = callback.WaitForResult();
7721 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7722}
7723
7724// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027725TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577726 HttpRequestInfo request;
7727 request.method = "GET";
7728 request.url = GURL("http://www.foo.com/");
7729 request.load_flags = 0;
7730
7731 MockRead data_reads[] = {
7732 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067733 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577734 };
7735
[email protected]31a2bfe2010-02-09 08:03:397736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077737 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577739
[email protected]49639fa2011-12-20 23:22:417740 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577741
7742 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077743 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577744
[email protected]49639fa2011-12-20 23:22:417745 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577746 EXPECT_EQ(ERR_IO_PENDING, rv);
7747
7748 rv = callback.WaitForResult();
7749 EXPECT_EQ(OK, rv);
7750
7751 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507752 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577753
[email protected]90499482013-06-01 00:39:507754 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577755 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7756
7757 std::string response_data;
7758 rv = ReadTransaction(trans.get(), &response_data);
7759 EXPECT_EQ(OK, rv);
7760 EXPECT_EQ("", response_data);
7761}
7762
7763// Make sure that a dropped connection while draining the body for auth
7764// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027765TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577766 HttpRequestInfo request;
7767 request.method = "GET";
7768 request.url = GURL("http://www.google.com/");
7769 request.load_flags = 0;
7770
7771 MockWrite data_writes1[] = {
7772 MockWrite("GET / HTTP/1.1\r\n"
7773 "Host: www.google.com\r\n"
7774 "Connection: keep-alive\r\n\r\n"),
7775 };
7776
7777 MockRead data_reads1[] = {
7778 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7779 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7780 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7781 MockRead("Content-Length: 14\r\n\r\n"),
7782 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067783 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577784 };
7785
[email protected]31a2bfe2010-02-09 08:03:397786 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7787 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077788 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577789
7790 // After calling trans->RestartWithAuth(), this is the request we should
7791 // be issuing -- the final header line contains the credentials.
7792 MockWrite data_writes2[] = {
7793 MockWrite("GET / HTTP/1.1\r\n"
7794 "Host: www.google.com\r\n"
7795 "Connection: keep-alive\r\n"
7796 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7797 };
7798
7799 // Lastly, the server responds with the actual content.
7800 MockRead data_reads2[] = {
7801 MockRead("HTTP/1.1 200 OK\r\n"),
7802 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7803 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067804 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577805 };
7806
[email protected]31a2bfe2010-02-09 08:03:397807 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7808 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077809 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077810 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577811
[email protected]49639fa2011-12-20 23:22:417812 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577813
[email protected]262eec82013-03-19 21:01:367814 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507815 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507816
[email protected]49639fa2011-12-20 23:22:417817 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577818 EXPECT_EQ(ERR_IO_PENDING, rv);
7819
7820 rv = callback1.WaitForResult();
7821 EXPECT_EQ(OK, rv);
7822
7823 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507824 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047825 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577826
[email protected]49639fa2011-12-20 23:22:417827 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577828
[email protected]49639fa2011-12-20 23:22:417829 rv = trans->RestartWithAuth(
7830 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577831 EXPECT_EQ(ERR_IO_PENDING, rv);
7832
7833 rv = callback2.WaitForResult();
7834 EXPECT_EQ(OK, rv);
7835
7836 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507837 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577838 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7839 EXPECT_EQ(100, response->headers->GetContentLength());
7840}
7841
7842// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027843TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077844 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577845
7846 HttpRequestInfo request;
7847 request.method = "GET";
7848 request.url = GURL("https://www.google.com/");
7849 request.load_flags = 0;
7850
7851 MockRead proxy_reads[] = {
7852 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067853 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577854 };
7855
[email protected]31a2bfe2010-02-09 08:03:397856 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067857 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577858
[email protected]bb88e1d32013-05-03 23:11:077859 session_deps_.socket_factory->AddSocketDataProvider(&data);
7860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577861
[email protected]49639fa2011-12-20 23:22:417862 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577863
[email protected]bb88e1d32013-05-03 23:11:077864 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577865
[email protected]3fe8d2f82013-10-17 08:56:077866 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577867 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577869
[email protected]49639fa2011-12-20 23:22:417870 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577871 EXPECT_EQ(ERR_IO_PENDING, rv);
7872
7873 rv = callback.WaitForResult();
7874 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7875}
7876
[email protected]23e482282013-06-14 16:08:027877TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467878 HttpRequestInfo request;
7879 request.method = "GET";
7880 request.url = GURL("http://www.google.com/");
7881 request.load_flags = 0;
7882
[email protected]3fe8d2f82013-10-17 08:56:077883 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277884 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277886
[email protected]e22e1362009-11-23 21:31:127887 MockRead data_reads[] = {
7888 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067889 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127890 };
[email protected]9492e4a2010-02-24 00:58:467891
7892 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077893 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467894
[email protected]49639fa2011-12-20 23:22:417895 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467896
[email protected]49639fa2011-12-20 23:22:417897 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467898 EXPECT_EQ(ERR_IO_PENDING, rv);
7899
7900 EXPECT_EQ(OK, callback.WaitForResult());
7901
7902 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507903 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467904
[email protected]90499482013-06-01 00:39:507905 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467906 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7907
7908 std::string response_data;
7909 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237910 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127911}
7912
[email protected]23e482282013-06-14 16:08:027913TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157914 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:527915 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:337916 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217917 UploadFileElementReader::ScopedOverridingContentLengthForTests
7918 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337919
[email protected]b2d26cfd2012-12-11 10:36:067920 ScopedVector<UploadElementReader> element_readers;
7921 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367922 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7923 temp_file_path,
7924 0,
7925 kuint64max,
7926 base::Time()));
[email protected]96c77a72013-09-24 09:49:207927 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277928
7929 HttpRequestInfo request;
7930 request.method = "POST";
7931 request.url = GURL("http://www.google.com/upload");
7932 request.upload_data_stream = &upload_data_stream;
7933 request.load_flags = 0;
7934
[email protected]3fe8d2f82013-10-17 08:56:077935 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277936 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077937 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:337938
7939 MockRead data_reads[] = {
7940 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7941 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067942 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337943 };
[email protected]31a2bfe2010-02-09 08:03:397944 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077945 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337946
[email protected]49639fa2011-12-20 23:22:417947 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337948
[email protected]49639fa2011-12-20 23:22:417949 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337950 EXPECT_EQ(ERR_IO_PENDING, rv);
7951
7952 rv = callback.WaitForResult();
7953 EXPECT_EQ(OK, rv);
7954
7955 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507956 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337957
[email protected]90499482013-06-01 00:39:507958 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337959 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7960
7961 std::string response_data;
7962 rv = ReadTransaction(trans.get(), &response_data);
7963 EXPECT_EQ(OK, rv);
7964 EXPECT_EQ("hello world", response_data);
7965
[email protected]dd3aa792013-07-16 19:10:237966 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:337967}
7968
[email protected]23e482282013-06-14 16:08:027969TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157970 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:527971 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:367972 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:307973 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:367974 temp_file_content.length()));
7975 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7976
[email protected]b2d26cfd2012-12-11 10:36:067977 ScopedVector<UploadElementReader> element_readers;
7978 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367979 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7980 temp_file,
7981 0,
7982 kuint64max,
7983 base::Time()));
[email protected]96c77a72013-09-24 09:49:207984 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277985
7986 HttpRequestInfo request;
7987 request.method = "POST";
7988 request.url = GURL("http://www.google.com/upload");
7989 request.upload_data_stream = &upload_data_stream;
7990 request.load_flags = 0;
7991
[email protected]999dd8c2013-11-12 06:45:547992 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:077993 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277994 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077995 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:367996
[email protected]999dd8c2013-11-12 06:45:547997 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077998 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367999
[email protected]49639fa2011-12-20 23:22:418000 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368001
[email protected]49639fa2011-12-20 23:22:418002 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368003 EXPECT_EQ(ERR_IO_PENDING, rv);
8004
8005 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548006 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368007
8008 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548009 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368010
[email protected]dd3aa792013-07-16 19:10:238011 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368012}
8013
[email protected]02cad5d2013-10-02 08:14:038014TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8015 class FakeUploadElementReader : public UploadElementReader {
8016 public:
8017 FakeUploadElementReader() {}
8018 virtual ~FakeUploadElementReader() {}
8019
8020 const CompletionCallback& callback() const { return callback_; }
8021
8022 // UploadElementReader overrides:
8023 virtual int Init(const CompletionCallback& callback) OVERRIDE {
8024 callback_ = callback;
8025 return ERR_IO_PENDING;
8026 }
8027 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
8028 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
8029 virtual int Read(IOBuffer* buf,
8030 int buf_length,
8031 const CompletionCallback& callback) OVERRIDE {
8032 return ERR_FAILED;
8033 }
8034
8035 private:
8036 CompletionCallback callback_;
8037 };
8038
8039 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8040 ScopedVector<UploadElementReader> element_readers;
8041 element_readers.push_back(fake_reader);
8042 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
8043
8044 HttpRequestInfo request;
8045 request.method = "POST";
8046 request.url = GURL("http://www.google.com/upload");
8047 request.upload_data_stream = &upload_data_stream;
8048 request.load_flags = 0;
8049
[email protected]3fe8d2f82013-10-17 08:56:078050 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038051 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:038053
8054 StaticSocketDataProvider data;
8055 session_deps_.socket_factory->AddSocketDataProvider(&data);
8056
8057 TestCompletionCallback callback;
8058 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8059 EXPECT_EQ(ERR_IO_PENDING, rv);
8060 base::MessageLoop::current()->RunUntilIdle();
8061
8062 // Transaction is pending on request body initialization.
8063 ASSERT_FALSE(fake_reader->callback().is_null());
8064
8065 // Return Init()'s result after the transaction gets destroyed.
8066 trans.reset();
8067 fake_reader->callback().Run(OK); // Should not crash.
8068}
8069
[email protected]aeefc9e82010-02-19 16:18:278070// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028071TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278072
8073 HttpRequestInfo request;
8074 request.method = "GET";
8075 request.url = GURL("http://www.google.com/");
8076 request.load_flags = 0;
8077
8078 // First transaction will request a resource and receive a Basic challenge
8079 // with realm="first_realm".
8080 MockWrite data_writes1[] = {
8081 MockWrite("GET / HTTP/1.1\r\n"
8082 "Host: www.google.com\r\n"
8083 "Connection: keep-alive\r\n"
8084 "\r\n"),
8085 };
8086 MockRead data_reads1[] = {
8087 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8088 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8089 "\r\n"),
8090 };
8091
8092 // After calling trans->RestartWithAuth(), provide an Authentication header
8093 // for first_realm. The server will reject and provide a challenge with
8094 // second_realm.
8095 MockWrite data_writes2[] = {
8096 MockWrite("GET / HTTP/1.1\r\n"
8097 "Host: www.google.com\r\n"
8098 "Connection: keep-alive\r\n"
8099 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8100 "\r\n"),
8101 };
8102 MockRead data_reads2[] = {
8103 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8104 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8105 "\r\n"),
8106 };
8107
8108 // This again fails, and goes back to first_realm. Make sure that the
8109 // entry is removed from cache.
8110 MockWrite data_writes3[] = {
8111 MockWrite("GET / HTTP/1.1\r\n"
8112 "Host: www.google.com\r\n"
8113 "Connection: keep-alive\r\n"
8114 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8115 "\r\n"),
8116 };
8117 MockRead data_reads3[] = {
8118 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8119 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8120 "\r\n"),
8121 };
8122
8123 // Try one last time (with the correct password) and get the resource.
8124 MockWrite data_writes4[] = {
8125 MockWrite("GET / HTTP/1.1\r\n"
8126 "Host: www.google.com\r\n"
8127 "Connection: keep-alive\r\n"
8128 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8129 "\r\n"),
8130 };
8131 MockRead data_reads4[] = {
8132 MockRead("HTTP/1.1 200 OK\r\n"
8133 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508134 "Content-Length: 5\r\n"
8135 "\r\n"
8136 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278137 };
8138
8139 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8140 data_writes1, arraysize(data_writes1));
8141 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8142 data_writes2, arraysize(data_writes2));
8143 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8144 data_writes3, arraysize(data_writes3));
8145 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8146 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078147 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8148 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8149 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8150 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278151
[email protected]49639fa2011-12-20 23:22:418152 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278153
[email protected]3fe8d2f82013-10-17 08:56:078154 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508155 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078156 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:508157
[email protected]aeefc9e82010-02-19 16:18:278158 // Issue the first request with Authorize headers. There should be a
8159 // password prompt for first_realm waiting to be filled in after the
8160 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418161 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278162 EXPECT_EQ(ERR_IO_PENDING, rv);
8163 rv = callback1.WaitForResult();
8164 EXPECT_EQ(OK, rv);
8165 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508166 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048167 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8168 ASSERT_FALSE(challenge == NULL);
8169 EXPECT_FALSE(challenge->is_proxy);
8170 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8171 EXPECT_EQ("first_realm", challenge->realm);
8172 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278173
8174 // Issue the second request with an incorrect password. There should be a
8175 // password prompt for second_realm waiting to be filled in after the
8176 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418177 TestCompletionCallback callback2;
8178 rv = trans->RestartWithAuth(
8179 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278180 EXPECT_EQ(ERR_IO_PENDING, rv);
8181 rv = callback2.WaitForResult();
8182 EXPECT_EQ(OK, rv);
8183 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508184 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048185 challenge = response->auth_challenge.get();
8186 ASSERT_FALSE(challenge == NULL);
8187 EXPECT_FALSE(challenge->is_proxy);
8188 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8189 EXPECT_EQ("second_realm", challenge->realm);
8190 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278191
8192 // Issue the third request with another incorrect password. There should be
8193 // a password prompt for first_realm waiting to be filled in. If the password
8194 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8195 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418196 TestCompletionCallback callback3;
8197 rv = trans->RestartWithAuth(
8198 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278199 EXPECT_EQ(ERR_IO_PENDING, rv);
8200 rv = callback3.WaitForResult();
8201 EXPECT_EQ(OK, rv);
8202 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508203 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048204 challenge = response->auth_challenge.get();
8205 ASSERT_FALSE(challenge == NULL);
8206 EXPECT_FALSE(challenge->is_proxy);
8207 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8208 EXPECT_EQ("first_realm", challenge->realm);
8209 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278210
8211 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418212 TestCompletionCallback callback4;
8213 rv = trans->RestartWithAuth(
8214 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278215 EXPECT_EQ(ERR_IO_PENDING, rv);
8216 rv = callback4.WaitForResult();
8217 EXPECT_EQ(OK, rv);
8218 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508219 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278220 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8221}
8222
[email protected]23e482282013-06-14 16:08:028223TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:038224 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:238225 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:428226
[email protected]8a0fc822013-06-27 20:52:438227 std::string alternate_protocol_http_header =
8228 GetAlternateProtocolHttpHeader();
8229
[email protected]564b4912010-03-09 16:30:428230 MockRead data_reads[] = {
8231 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438232 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428233 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068234 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428235 };
8236
8237 HttpRequestInfo request;
8238 request.method = "GET";
8239 request.url = GURL("http://www.google.com/");
8240 request.load_flags = 0;
8241
8242 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8243
[email protected]bb88e1d32013-05-03 23:11:078244 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428245
[email protected]49639fa2011-12-20 23:22:418246 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428247
[email protected]bb88e1d32013-05-03 23:11:078248 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368249 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508250 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428251
[email protected]49639fa2011-12-20 23:22:418252 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428253 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538254
[email protected]2fbaecf22010-07-22 22:20:358255 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558256 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538257 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428258 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538259 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428260
8261 EXPECT_EQ(OK, callback.WaitForResult());
8262
8263 const HttpResponseInfo* response = trans->GetResponseInfo();
8264 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508265 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428266 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538267 EXPECT_FALSE(response->was_fetched_via_spdy);
8268 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428269
8270 std::string response_data;
8271 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8272 EXPECT_EQ("hello world", response_data);
8273
[email protected]17291a022011-10-10 07:32:538274 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8275 const PortAlternateProtocolPair alternate =
8276 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8277 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428278 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438279 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428280 EXPECT_TRUE(expected_alternate.Equals(alternate));
8281}
8282
[email protected]23e482282013-06-14 16:08:028283TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238284 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388285 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428286
8287 HttpRequestInfo request;
8288 request.method = "GET";
8289 request.url = GURL("http://www.google.com/");
8290 request.load_flags = 0;
8291
[email protected]d973e99a2012-02-17 21:02:368292 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428293 StaticSocketDataProvider first_data;
8294 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078295 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428296
8297 MockRead data_reads[] = {
8298 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8299 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068300 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428301 };
8302 StaticSocketDataProvider second_data(
8303 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078304 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428305
[email protected]bb88e1d32013-05-03 23:11:078306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428307
[email protected]30d4c022013-07-18 22:58:168308 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538309 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118310 // Port must be < 1024, or the header will be ignored (since initial port was
8311 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538312 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118313 HostPortPair::FromURL(request.url),
8314 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438315 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428316
[email protected]262eec82013-03-19 21:01:368317 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508318 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418319 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428320
[email protected]49639fa2011-12-20 23:22:418321 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428322 EXPECT_EQ(ERR_IO_PENDING, rv);
8323 EXPECT_EQ(OK, callback.WaitForResult());
8324
8325 const HttpResponseInfo* response = trans->GetResponseInfo();
8326 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508327 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428328 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8329
8330 std::string response_data;
8331 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8332 EXPECT_EQ("hello world", response_data);
8333
[email protected]17291a022011-10-10 07:32:538334 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118335 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538336 const PortAlternateProtocolPair alternate =
8337 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118338 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538339 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428340}
8341
[email protected]23e482282013-06-14 16:08:028342TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238343 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118344 // Ensure that we're not allowed to redirect traffic via an alternate
8345 // protocol to an unrestricted (port >= 1024) when the original traffic was
8346 // on a restricted port (port < 1024). Ensure that we can redirect in all
8347 // other cases.
8348 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118349
8350 HttpRequestInfo restricted_port_request;
8351 restricted_port_request.method = "GET";
8352 restricted_port_request.url = GURL("http://www.google.com:1023/");
8353 restricted_port_request.load_flags = 0;
8354
[email protected]d973e99a2012-02-17 21:02:368355 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118356 StaticSocketDataProvider first_data;
8357 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078358 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118359
8360 MockRead data_reads[] = {
8361 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8362 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068363 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118364 };
8365 StaticSocketDataProvider second_data(
8366 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078367 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118368
[email protected]bb88e1d32013-05-03 23:11:078369 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118370
[email protected]30d4c022013-07-18 22:58:168371 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538372 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118373 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538374 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118375 HostPortPair::FromURL(restricted_port_request.url),
8376 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438377 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118378
[email protected]262eec82013-03-19 21:01:368379 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418381 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118382
[email protected]49639fa2011-12-20 23:22:418383 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368384 &restricted_port_request,
8385 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118386 EXPECT_EQ(ERR_IO_PENDING, rv);
8387 // Invalid change to unrestricted port should fail.
8388 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198389}
[email protected]3912662a32011-10-04 00:51:118390
[email protected]23e482282013-06-14 16:08:028391TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198392 AlternateProtocolPortRestrictedPermitted) {
8393 // Ensure that we're allowed to redirect traffic via an alternate
8394 // protocol to an unrestricted (port >= 1024) when the original traffic was
8395 // on a restricted port (port < 1024) if we set
8396 // enable_user_alternate_protocol_ports.
8397
8398 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078399 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198400
8401 HttpRequestInfo restricted_port_request;
8402 restricted_port_request.method = "GET";
8403 restricted_port_request.url = GURL("http://www.google.com:1023/");
8404 restricted_port_request.load_flags = 0;
8405
8406 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8407 StaticSocketDataProvider first_data;
8408 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078409 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198410
8411 MockRead data_reads[] = {
8412 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8413 MockRead("hello world"),
8414 MockRead(ASYNC, OK),
8415 };
8416 StaticSocketDataProvider second_data(
8417 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078418 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198419
[email protected]bb88e1d32013-05-03 23:11:078420 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198421
[email protected]30d4c022013-07-18 22:58:168422 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198423 session->http_server_properties();
8424 const int kUnrestrictedAlternatePort = 1024;
8425 http_server_properties->SetAlternateProtocol(
8426 HostPortPair::FromURL(restricted_port_request.url),
8427 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438428 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198429
[email protected]262eec82013-03-19 21:01:368430 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508431 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198432 TestCompletionCallback callback;
8433
8434 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368435 &restricted_port_request,
8436 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198437 // Change to unrestricted port should succeed.
8438 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118439}
8440
[email protected]23e482282013-06-14 16:08:028441TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238442 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118443 // Ensure that we're not allowed to redirect traffic via an alternate
8444 // protocol to an unrestricted (port >= 1024) when the original traffic was
8445 // on a restricted port (port < 1024). Ensure that we can redirect in all
8446 // other cases.
8447 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118448
8449 HttpRequestInfo restricted_port_request;
8450 restricted_port_request.method = "GET";
8451 restricted_port_request.url = GURL("http://www.google.com:1023/");
8452 restricted_port_request.load_flags = 0;
8453
[email protected]d973e99a2012-02-17 21:02:368454 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118455 StaticSocketDataProvider first_data;
8456 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078457 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118458
8459 MockRead data_reads[] = {
8460 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8461 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068462 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118463 };
8464 StaticSocketDataProvider second_data(
8465 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078466 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118467
[email protected]bb88e1d32013-05-03 23:11:078468 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118469
[email protected]30d4c022013-07-18 22:58:168470 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538471 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118472 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538473 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118474 HostPortPair::FromURL(restricted_port_request.url),
8475 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438476 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118477
[email protected]262eec82013-03-19 21:01:368478 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508479 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418480 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118481
[email protected]49639fa2011-12-20 23:22:418482 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368483 &restricted_port_request,
8484 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118485 EXPECT_EQ(ERR_IO_PENDING, rv);
8486 // Valid change to restricted port should pass.
8487 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118488}
8489
[email protected]23e482282013-06-14 16:08:028490TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238491 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118492 // Ensure that we're not allowed to redirect traffic via an alternate
8493 // protocol to an unrestricted (port >= 1024) when the original traffic was
8494 // on a restricted port (port < 1024). Ensure that we can redirect in all
8495 // other cases.
8496 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118497
8498 HttpRequestInfo unrestricted_port_request;
8499 unrestricted_port_request.method = "GET";
8500 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8501 unrestricted_port_request.load_flags = 0;
8502
[email protected]d973e99a2012-02-17 21:02:368503 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118504 StaticSocketDataProvider first_data;
8505 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078506 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118507
8508 MockRead data_reads[] = {
8509 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8510 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068511 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118512 };
8513 StaticSocketDataProvider second_data(
8514 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078515 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118516
[email protected]bb88e1d32013-05-03 23:11:078517 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118518
[email protected]30d4c022013-07-18 22:58:168519 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538520 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118521 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538522 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118523 HostPortPair::FromURL(unrestricted_port_request.url),
8524 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438525 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118526
[email protected]262eec82013-03-19 21:01:368527 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508528 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418529 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118530
[email protected]49639fa2011-12-20 23:22:418531 int rv = trans->Start(
8532 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118533 EXPECT_EQ(ERR_IO_PENDING, rv);
8534 // Valid change to restricted port should pass.
8535 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118536}
8537
[email protected]23e482282013-06-14 16:08:028538TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238539 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118540 // Ensure that we're not allowed to redirect traffic via an alternate
8541 // protocol to an unrestricted (port >= 1024) when the original traffic was
8542 // on a restricted port (port < 1024). Ensure that we can redirect in all
8543 // other cases.
8544 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118545
8546 HttpRequestInfo unrestricted_port_request;
8547 unrestricted_port_request.method = "GET";
8548 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8549 unrestricted_port_request.load_flags = 0;
8550
[email protected]d973e99a2012-02-17 21:02:368551 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118552 StaticSocketDataProvider first_data;
8553 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078554 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118555
8556 MockRead data_reads[] = {
8557 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8558 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068559 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118560 };
8561 StaticSocketDataProvider second_data(
8562 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078563 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118564
[email protected]bb88e1d32013-05-03 23:11:078565 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118566
[email protected]30d4c022013-07-18 22:58:168567 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538568 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118569 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538570 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118571 HostPortPair::FromURL(unrestricted_port_request.url),
8572 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438573 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118574
[email protected]262eec82013-03-19 21:01:368575 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508576 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418577 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118578
[email protected]49639fa2011-12-20 23:22:418579 int rv = trans->Start(
8580 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118581 EXPECT_EQ(ERR_IO_PENDING, rv);
8582 // Valid change to an unrestricted port should pass.
8583 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118584}
8585
[email protected]23e482282013-06-14 16:08:028586TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238587 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028588 // Ensure that we're not allowed to redirect traffic via an alternate
8589 // protocol to an unsafe port, and that we resume the second
8590 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8591 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028592
8593 HttpRequestInfo request;
8594 request.method = "GET";
8595 request.url = GURL("http://www.google.com/");
8596 request.load_flags = 0;
8597
8598 // The alternate protocol request will error out before we attempt to connect,
8599 // so only the standard HTTP request will try to connect.
8600 MockRead data_reads[] = {
8601 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8602 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068603 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028604 };
8605 StaticSocketDataProvider data(
8606 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078607 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028608
[email protected]bb88e1d32013-05-03 23:11:078609 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028610
[email protected]30d4c022013-07-18 22:58:168611 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028612 session->http_server_properties();
8613 const int kUnsafePort = 7;
8614 http_server_properties->SetAlternateProtocol(
8615 HostPortPair::FromURL(request.url),
8616 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438617 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028618
[email protected]262eec82013-03-19 21:01:368619 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508620 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028621 TestCompletionCallback callback;
8622
8623 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8624 EXPECT_EQ(ERR_IO_PENDING, rv);
8625 // The HTTP request should succeed.
8626 EXPECT_EQ(OK, callback.WaitForResult());
8627
8628 // Disable alternate protocol before the asserts.
8629 HttpStreamFactory::set_use_alternate_protocols(false);
8630
8631 const HttpResponseInfo* response = trans->GetResponseInfo();
8632 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508633 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028634 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8635
8636 std::string response_data;
8637 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8638 EXPECT_EQ("hello world", response_data);
8639}
8640
[email protected]23e482282013-06-14 16:08:028641TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388642 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038643 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548644
8645 HttpRequestInfo request;
8646 request.method = "GET";
8647 request.url = GURL("http://www.google.com/");
8648 request.load_flags = 0;
8649
[email protected]8a0fc822013-06-27 20:52:438650 std::string alternate_protocol_http_header =
8651 GetAlternateProtocolHttpHeader();
8652
[email protected]2ff8b312010-04-26 22:20:548653 MockRead data_reads[] = {
8654 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438655 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548656 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178657 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8658 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548659 };
8660
8661 StaticSocketDataProvider first_transaction(
8662 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078663 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548664
[email protected]8ddf8322012-02-23 18:08:068665 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028666 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078667 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548668
[email protected]cdf8f7e72013-05-23 10:56:468669 scoped_ptr<SpdyFrame> req(
8670 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138671 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548672
[email protected]23e482282013-06-14 16:08:028673 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8674 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548675 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138676 CreateMockRead(*resp),
8677 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068678 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548679 };
8680
[email protected]dd54bd82012-07-19 23:44:578681 DelayedSocketData spdy_data(
8682 1, // wait for one write to finish before reading.
8683 spdy_reads, arraysize(spdy_reads),
8684 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078685 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548686
[email protected]d973e99a2012-02-17 21:02:368687 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558688 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8689 NULL, 0, NULL, 0);
8690 hanging_non_alternate_protocol_socket.set_connect_data(
8691 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078692 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558693 &hanging_non_alternate_protocol_socket);
8694
[email protected]49639fa2011-12-20 23:22:418695 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548696
[email protected]bb88e1d32013-05-03 23:11:078697 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368698 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508699 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548700
[email protected]49639fa2011-12-20 23:22:418701 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548702 EXPECT_EQ(ERR_IO_PENDING, rv);
8703 EXPECT_EQ(OK, callback.WaitForResult());
8704
8705 const HttpResponseInfo* response = trans->GetResponseInfo();
8706 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508707 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548708 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8709
8710 std::string response_data;
8711 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8712 EXPECT_EQ("hello world", response_data);
8713
[email protected]90499482013-06-01 00:39:508714 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548715
[email protected]49639fa2011-12-20 23:22:418716 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548717 EXPECT_EQ(ERR_IO_PENDING, rv);
8718 EXPECT_EQ(OK, callback.WaitForResult());
8719
8720 response = trans->GetResponseInfo();
8721 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508722 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548723 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538724 EXPECT_TRUE(response->was_fetched_via_spdy);
8725 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548726
8727 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8728 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548729}
8730
[email protected]23e482282013-06-14 16:08:028731TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558732 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038733 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558734
8735 HttpRequestInfo request;
8736 request.method = "GET";
8737 request.url = GURL("http://www.google.com/");
8738 request.load_flags = 0;
8739
[email protected]8a0fc822013-06-27 20:52:438740 std::string alternate_protocol_http_header =
8741 GetAlternateProtocolHttpHeader();
8742
[email protected]2d6728692011-03-12 01:39:558743 MockRead data_reads[] = {
8744 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438745 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558746 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178747 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068748 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558749 };
8750
8751 StaticSocketDataProvider first_transaction(
8752 data_reads, arraysize(data_reads), NULL, 0);
8753 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078754 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558755
[email protected]d973e99a2012-02-17 21:02:368756 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558757 StaticSocketDataProvider hanging_socket(
8758 NULL, 0, NULL, 0);
8759 hanging_socket.set_connect_data(never_finishing_connect);
8760 // Socket 2 and 3 are the hanging Alternate-Protocol and
8761 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078762 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8763 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558764
[email protected]8ddf8322012-02-23 18:08:068765 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028766 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078767 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558768
[email protected]cdf8f7e72013-05-23 10:56:468769 scoped_ptr<SpdyFrame> req1(
8770 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8771 scoped_ptr<SpdyFrame> req2(
8772 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558773 MockWrite spdy_writes[] = {
8774 CreateMockWrite(*req1),
8775 CreateMockWrite(*req2),
8776 };
[email protected]23e482282013-06-14 16:08:028777 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8778 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8779 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8780 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558781 MockRead spdy_reads[] = {
8782 CreateMockRead(*resp1),
8783 CreateMockRead(*data1),
8784 CreateMockRead(*resp2),
8785 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068786 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558787 };
8788
[email protected]dd54bd82012-07-19 23:44:578789 DelayedSocketData spdy_data(
8790 2, // wait for writes to finish before reading.
8791 spdy_reads, arraysize(spdy_reads),
8792 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558793 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078794 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558795
8796 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078797 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558798
[email protected]bb88e1d32013-05-03 23:11:078799 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418800 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508801 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558802
[email protected]49639fa2011-12-20 23:22:418803 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558804 EXPECT_EQ(ERR_IO_PENDING, rv);
8805 EXPECT_EQ(OK, callback1.WaitForResult());
8806
8807 const HttpResponseInfo* response = trans1.GetResponseInfo();
8808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508809 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8811
8812 std::string response_data;
8813 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8814 EXPECT_EQ("hello world", response_data);
8815
[email protected]49639fa2011-12-20 23:22:418816 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508817 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418818 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558819 EXPECT_EQ(ERR_IO_PENDING, rv);
8820
[email protected]49639fa2011-12-20 23:22:418821 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508822 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418823 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558824 EXPECT_EQ(ERR_IO_PENDING, rv);
8825
8826 EXPECT_EQ(OK, callback2.WaitForResult());
8827 EXPECT_EQ(OK, callback3.WaitForResult());
8828
8829 response = trans2.GetResponseInfo();
8830 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508831 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558832 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8833 EXPECT_TRUE(response->was_fetched_via_spdy);
8834 EXPECT_TRUE(response->was_npn_negotiated);
8835 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8836 EXPECT_EQ("hello!", response_data);
8837
8838 response = trans3.GetResponseInfo();
8839 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508840 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558841 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8842 EXPECT_TRUE(response->was_fetched_via_spdy);
8843 EXPECT_TRUE(response->was_npn_negotiated);
8844 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8845 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558846}
8847
[email protected]23e482282013-06-14 16:08:028848TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558849 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038850 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558851
8852 HttpRequestInfo request;
8853 request.method = "GET";
8854 request.url = GURL("http://www.google.com/");
8855 request.load_flags = 0;
8856
[email protected]8a0fc822013-06-27 20:52:438857 std::string alternate_protocol_http_header =
8858 GetAlternateProtocolHttpHeader();
8859
[email protected]2d6728692011-03-12 01:39:558860 MockRead data_reads[] = {
8861 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438862 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558863 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178864 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068865 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558866 };
8867
8868 StaticSocketDataProvider first_transaction(
8869 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078870 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558871
[email protected]8ddf8322012-02-23 18:08:068872 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028873 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558875
[email protected]d973e99a2012-02-17 21:02:368876 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558877 StaticSocketDataProvider hanging_alternate_protocol_socket(
8878 NULL, 0, NULL, 0);
8879 hanging_alternate_protocol_socket.set_connect_data(
8880 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078881 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558882 &hanging_alternate_protocol_socket);
8883
8884 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558886
[email protected]49639fa2011-12-20 23:22:418887 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558888
[email protected]bb88e1d32013-05-03 23:11:078889 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368890 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558892
[email protected]49639fa2011-12-20 23:22:418893 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558894 EXPECT_EQ(ERR_IO_PENDING, rv);
8895 EXPECT_EQ(OK, callback.WaitForResult());
8896
8897 const HttpResponseInfo* response = trans->GetResponseInfo();
8898 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508899 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558900 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8901
8902 std::string response_data;
8903 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8904 EXPECT_EQ("hello world", response_data);
8905
[email protected]90499482013-06-01 00:39:508906 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558907
[email protected]49639fa2011-12-20 23:22:418908 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558909 EXPECT_EQ(ERR_IO_PENDING, rv);
8910 EXPECT_EQ(OK, callback.WaitForResult());
8911
8912 response = trans->GetResponseInfo();
8913 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508914 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558915 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8916 EXPECT_FALSE(response->was_fetched_via_spdy);
8917 EXPECT_FALSE(response->was_npn_negotiated);
8918
8919 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8920 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558921}
8922
[email protected]631f1322010-04-30 17:59:118923class CapturingProxyResolver : public ProxyResolver {
8924 public:
8925 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8926 virtual ~CapturingProxyResolver() {}
8927
8928 virtual int GetProxyForURL(const GURL& url,
8929 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318930 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118931 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168932 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408933 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8934 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428935 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118936 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428937 return OK;
[email protected]631f1322010-04-30 17:59:118938 }
8939
[email protected]46fadfd2013-02-06 09:40:168940 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118941 NOTREACHED();
8942 }
8943
[email protected]f2c971f2011-11-08 00:33:178944 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8945 NOTREACHED();
8946 return LOAD_STATE_IDLE;
8947 }
8948
[email protected]46fadfd2013-02-06 09:40:168949 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408950 NOTREACHED();
8951 }
8952
[email protected]24476402010-07-20 20:55:178953 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168954 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428955 return OK;
[email protected]631f1322010-04-30 17:59:118956 }
8957
[email protected]24476402010-07-20 20:55:178958 const std::vector<GURL>& resolved() const { return resolved_; }
8959
8960 private:
[email protected]631f1322010-04-30 17:59:118961 std::vector<GURL> resolved_;
8962
8963 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8964};
8965
[email protected]23e482282013-06-14 16:08:028966TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238967 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388968 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038969 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118970
8971 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428972 proxy_config.set_auto_detect(true);
8973 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118974
[email protected]631f1322010-04-30 17:59:118975 CapturingProxyResolver* capturing_proxy_resolver =
8976 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078977 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388978 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8979 NULL));
[email protected]029c83b62013-01-24 05:28:208980 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078981 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118982
8983 HttpRequestInfo request;
8984 request.method = "GET";
8985 request.url = GURL("http://www.google.com/");
8986 request.load_flags = 0;
8987
[email protected]8a0fc822013-06-27 20:52:438988 std::string alternate_protocol_http_header =
8989 GetAlternateProtocolHttpHeader();
8990
[email protected]631f1322010-04-30 17:59:118991 MockRead data_reads[] = {
8992 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438993 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118994 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068996 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118997 };
8998
8999 StaticSocketDataProvider first_transaction(
9000 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079001 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119002
[email protected]8ddf8322012-02-23 18:08:069003 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029004 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119006
[email protected]cdf8f7e72013-05-23 10:56:469007 scoped_ptr<SpdyFrame> req(
9008 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119009 MockWrite spdy_writes[] = {
9010 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9011 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429012 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469013 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119014 };
9015
[email protected]d911f1b2010-05-05 22:39:429016 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9017
[email protected]23e482282013-06-14 16:08:029018 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9019 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119020 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069021 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139022 CreateMockRead(*resp.get(), 4), // 2, 4
9023 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069024 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119025 };
9026
[email protected]dd54bd82012-07-19 23:44:579027 OrderedSocketData spdy_data(
9028 spdy_reads, arraysize(spdy_reads),
9029 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079030 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119031
[email protected]d973e99a2012-02-17 21:02:369032 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559033 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9034 NULL, 0, NULL, 0);
9035 hanging_non_alternate_protocol_socket.set_connect_data(
9036 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079037 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559038 &hanging_non_alternate_protocol_socket);
9039
[email protected]49639fa2011-12-20 23:22:419040 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119041
[email protected]bb88e1d32013-05-03 23:11:079042 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369043 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119045
[email protected]49639fa2011-12-20 23:22:419046 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119047 EXPECT_EQ(ERR_IO_PENDING, rv);
9048 EXPECT_EQ(OK, callback.WaitForResult());
9049
9050 const HttpResponseInfo* response = trans->GetResponseInfo();
9051 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509052 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119053 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539054 EXPECT_FALSE(response->was_fetched_via_spdy);
9055 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119056
9057 std::string response_data;
9058 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9059 EXPECT_EQ("hello world", response_data);
9060
[email protected]90499482013-06-01 00:39:509061 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119062
[email protected]49639fa2011-12-20 23:22:419063 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119064 EXPECT_EQ(ERR_IO_PENDING, rv);
9065 EXPECT_EQ(OK, callback.WaitForResult());
9066
9067 response = trans->GetResponseInfo();
9068 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509069 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119070 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539071 EXPECT_TRUE(response->was_fetched_via_spdy);
9072 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119073
9074 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9075 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559076 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429077 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119078 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429079 EXPECT_EQ("https://www.google.com/",
9080 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119081
[email protected]029c83b62013-01-24 05:28:209082 LoadTimingInfo load_timing_info;
9083 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9084 TestLoadTimingNotReusedWithPac(load_timing_info,
9085 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119086}
[email protected]631f1322010-04-30 17:59:119087
[email protected]23e482282013-06-14 16:08:029088TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549089 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:389090 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039091 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:549092
9093 HttpRequestInfo request;
9094 request.method = "GET";
9095 request.url = GURL("http://www.google.com/");
9096 request.load_flags = 0;
9097
[email protected]8a0fc822013-06-27 20:52:439098 std::string alternate_protocol_http_header =
9099 GetAlternateProtocolHttpHeader();
9100
[email protected]2ff8b312010-04-26 22:20:549101 MockRead data_reads[] = {
9102 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439103 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549104 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069105 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549106 };
9107
9108 StaticSocketDataProvider first_transaction(
9109 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079110 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549111
[email protected]8ddf8322012-02-23 18:08:069112 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029113 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549115
[email protected]cdf8f7e72013-05-23 10:56:469116 scoped_ptr<SpdyFrame> req(
9117 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139118 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549119
[email protected]23e482282013-06-14 16:08:029120 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9121 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549122 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139123 CreateMockRead(*resp),
9124 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069125 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549126 };
9127
[email protected]dd54bd82012-07-19 23:44:579128 DelayedSocketData spdy_data(
9129 1, // wait for one write to finish before reading.
9130 spdy_reads, arraysize(spdy_reads),
9131 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079132 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549133
[email protected]83039bb2011-12-09 18:43:559134 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549135
[email protected]bb88e1d32013-05-03 23:11:079136 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549137
[email protected]262eec82013-03-19 21:01:369138 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549140
[email protected]49639fa2011-12-20 23:22:419141 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549142 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419143 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549144
9145 const HttpResponseInfo* response = trans->GetResponseInfo();
9146 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509147 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549148 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9149
9150 std::string response_data;
9151 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9152 EXPECT_EQ("hello world", response_data);
9153
9154 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389155 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409156 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9157 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:279158 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269159 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389160
[email protected]90499482013-06-01 00:39:509161 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549162
[email protected]49639fa2011-12-20 23:22:419163 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549164 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419165 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549166
9167 response = trans->GetResponseInfo();
9168 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509169 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549170 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539171 EXPECT_TRUE(response->was_fetched_via_spdy);
9172 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549173
9174 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9175 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429176}
9177
[email protected]044de0642010-06-17 10:42:159178// GenerateAuthToken is a mighty big test.
9179// It tests all permutation of GenerateAuthToken behavior:
9180// - Synchronous and Asynchronous completion.
9181// - OK or error on completion.
9182// - Direct connection, non-authenticating proxy, and authenticating proxy.
9183// - HTTP or HTTPS backend (to include proxy tunneling).
9184// - Non-authenticating and authenticating backend.
9185//
[email protected]fe3b7dc2012-02-03 19:52:099186// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159187// problems generating an auth token for an authenticating proxy, we don't
9188// need to test all permutations of the backend server).
9189//
9190// The test proceeds by going over each of the configuration cases, and
9191// potentially running up to three rounds in each of the tests. The TestConfig
9192// specifies both the configuration for the test as well as the expectations
9193// for the results.
[email protected]23e482282013-06-14 16:08:029194TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509195 static const char kServer[] = "http://www.example.com";
9196 static const char kSecureServer[] = "https://www.example.com";
9197 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159198 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9199
9200 enum AuthTiming {
9201 AUTH_NONE,
9202 AUTH_SYNC,
9203 AUTH_ASYNC,
9204 };
9205
9206 const MockWrite kGet(
9207 "GET / HTTP/1.1\r\n"
9208 "Host: www.example.com\r\n"
9209 "Connection: keep-alive\r\n\r\n");
9210 const MockWrite kGetProxy(
9211 "GET http://www.example.com/ HTTP/1.1\r\n"
9212 "Host: www.example.com\r\n"
9213 "Proxy-Connection: keep-alive\r\n\r\n");
9214 const MockWrite kGetAuth(
9215 "GET / HTTP/1.1\r\n"
9216 "Host: www.example.com\r\n"
9217 "Connection: keep-alive\r\n"
9218 "Authorization: auth_token\r\n\r\n");
9219 const MockWrite kGetProxyAuth(
9220 "GET http://www.example.com/ HTTP/1.1\r\n"
9221 "Host: www.example.com\r\n"
9222 "Proxy-Connection: keep-alive\r\n"
9223 "Proxy-Authorization: auth_token\r\n\r\n");
9224 const MockWrite kGetAuthThroughProxy(
9225 "GET http://www.example.com/ HTTP/1.1\r\n"
9226 "Host: www.example.com\r\n"
9227 "Proxy-Connection: keep-alive\r\n"
9228 "Authorization: auth_token\r\n\r\n");
9229 const MockWrite kGetAuthWithProxyAuth(
9230 "GET http://www.example.com/ HTTP/1.1\r\n"
9231 "Host: www.example.com\r\n"
9232 "Proxy-Connection: keep-alive\r\n"
9233 "Proxy-Authorization: auth_token\r\n"
9234 "Authorization: auth_token\r\n\r\n");
9235 const MockWrite kConnect(
9236 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9237 "Host: www.example.com\r\n"
9238 "Proxy-Connection: keep-alive\r\n\r\n");
9239 const MockWrite kConnectProxyAuth(
9240 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9241 "Host: www.example.com\r\n"
9242 "Proxy-Connection: keep-alive\r\n"
9243 "Proxy-Authorization: auth_token\r\n\r\n");
9244
9245 const MockRead kSuccess(
9246 "HTTP/1.1 200 OK\r\n"
9247 "Content-Type: text/html; charset=iso-8859-1\r\n"
9248 "Content-Length: 3\r\n\r\n"
9249 "Yes");
9250 const MockRead kFailure(
9251 "Should not be called.");
9252 const MockRead kServerChallenge(
9253 "HTTP/1.1 401 Unauthorized\r\n"
9254 "WWW-Authenticate: Mock realm=server\r\n"
9255 "Content-Type: text/html; charset=iso-8859-1\r\n"
9256 "Content-Length: 14\r\n\r\n"
9257 "Unauthorized\r\n");
9258 const MockRead kProxyChallenge(
9259 "HTTP/1.1 407 Unauthorized\r\n"
9260 "Proxy-Authenticate: Mock realm=proxy\r\n"
9261 "Proxy-Connection: close\r\n"
9262 "Content-Type: text/html; charset=iso-8859-1\r\n"
9263 "Content-Length: 14\r\n\r\n"
9264 "Unauthorized\r\n");
9265 const MockRead kProxyConnected(
9266 "HTTP/1.1 200 Connection Established\r\n\r\n");
9267
9268 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9269 // no constructors, but the C++ compiler on Windows warns about
9270 // unspecified data in compound literals. So, moved to using constructors,
9271 // and TestRound's created with the default constructor should not be used.
9272 struct TestRound {
9273 TestRound()
9274 : expected_rv(ERR_UNEXPECTED),
9275 extra_write(NULL),
9276 extra_read(NULL) {
9277 }
9278 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9279 int expected_rv_arg)
9280 : write(write_arg),
9281 read(read_arg),
9282 expected_rv(expected_rv_arg),
9283 extra_write(NULL),
9284 extra_read(NULL) {
9285 }
9286 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9287 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019288 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159289 : write(write_arg),
9290 read(read_arg),
9291 expected_rv(expected_rv_arg),
9292 extra_write(extra_write_arg),
9293 extra_read(extra_read_arg) {
9294 }
9295 MockWrite write;
9296 MockRead read;
9297 int expected_rv;
9298 const MockWrite* extra_write;
9299 const MockRead* extra_read;
9300 };
9301
9302 static const int kNoSSL = 500;
9303
9304 struct TestConfig {
9305 const char* proxy_url;
9306 AuthTiming proxy_auth_timing;
9307 int proxy_auth_rv;
9308 const char* server_url;
9309 AuthTiming server_auth_timing;
9310 int server_auth_rv;
9311 int num_auth_rounds;
9312 int first_ssl_round;
9313 TestRound rounds[3];
9314 } test_configs[] = {
9315 // Non-authenticating HTTP server with a direct connection.
9316 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9317 { TestRound(kGet, kSuccess, OK)}},
9318 // Authenticating HTTP server with a direct connection.
9319 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9320 { TestRound(kGet, kServerChallenge, OK),
9321 TestRound(kGetAuth, kSuccess, OK)}},
9322 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9323 { TestRound(kGet, kServerChallenge, OK),
9324 TestRound(kGetAuth, kFailure, kAuthErr)}},
9325 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9326 { TestRound(kGet, kServerChallenge, OK),
9327 TestRound(kGetAuth, kSuccess, OK)}},
9328 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9329 { TestRound(kGet, kServerChallenge, OK),
9330 TestRound(kGetAuth, kFailure, kAuthErr)}},
9331 // Non-authenticating HTTP server through a non-authenticating proxy.
9332 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9333 { TestRound(kGetProxy, kSuccess, OK)}},
9334 // Authenticating HTTP server through a non-authenticating proxy.
9335 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9336 { TestRound(kGetProxy, kServerChallenge, OK),
9337 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9338 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9339 { TestRound(kGetProxy, kServerChallenge, OK),
9340 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9341 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9342 { TestRound(kGetProxy, kServerChallenge, OK),
9343 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9344 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9345 { TestRound(kGetProxy, kServerChallenge, OK),
9346 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9347 // Non-authenticating HTTP server through an authenticating proxy.
9348 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9349 { TestRound(kGetProxy, kProxyChallenge, OK),
9350 TestRound(kGetProxyAuth, kSuccess, OK)}},
9351 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9352 { TestRound(kGetProxy, kProxyChallenge, OK),
9353 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9354 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9355 { TestRound(kGetProxy, kProxyChallenge, OK),
9356 TestRound(kGetProxyAuth, kSuccess, OK)}},
9357 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9358 { TestRound(kGetProxy, kProxyChallenge, OK),
9359 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9360 // Authenticating HTTP server through an authenticating proxy.
9361 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9362 { TestRound(kGetProxy, kProxyChallenge, OK),
9363 TestRound(kGetProxyAuth, kServerChallenge, OK),
9364 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9365 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9366 { TestRound(kGetProxy, kProxyChallenge, OK),
9367 TestRound(kGetProxyAuth, kServerChallenge, OK),
9368 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9369 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9370 { TestRound(kGetProxy, kProxyChallenge, OK),
9371 TestRound(kGetProxyAuth, kServerChallenge, OK),
9372 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9373 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9374 { TestRound(kGetProxy, kProxyChallenge, OK),
9375 TestRound(kGetProxyAuth, kServerChallenge, OK),
9376 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9377 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9378 { TestRound(kGetProxy, kProxyChallenge, OK),
9379 TestRound(kGetProxyAuth, kServerChallenge, OK),
9380 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9381 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9382 { TestRound(kGetProxy, kProxyChallenge, OK),
9383 TestRound(kGetProxyAuth, kServerChallenge, OK),
9384 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9385 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9386 { TestRound(kGetProxy, kProxyChallenge, OK),
9387 TestRound(kGetProxyAuth, kServerChallenge, OK),
9388 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9389 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9390 { TestRound(kGetProxy, kProxyChallenge, OK),
9391 TestRound(kGetProxyAuth, kServerChallenge, OK),
9392 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9393 // Non-authenticating HTTPS server with a direct connection.
9394 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9395 { TestRound(kGet, kSuccess, OK)}},
9396 // Authenticating HTTPS server with a direct connection.
9397 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9398 { TestRound(kGet, kServerChallenge, OK),
9399 TestRound(kGetAuth, kSuccess, OK)}},
9400 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9401 { TestRound(kGet, kServerChallenge, OK),
9402 TestRound(kGetAuth, kFailure, kAuthErr)}},
9403 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9404 { TestRound(kGet, kServerChallenge, OK),
9405 TestRound(kGetAuth, kSuccess, OK)}},
9406 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9407 { TestRound(kGet, kServerChallenge, OK),
9408 TestRound(kGetAuth, kFailure, kAuthErr)}},
9409 // Non-authenticating HTTPS server with a non-authenticating proxy.
9410 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9411 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9412 // Authenticating HTTPS server through a non-authenticating proxy.
9413 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9414 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9415 TestRound(kGetAuth, kSuccess, OK)}},
9416 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9417 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9418 TestRound(kGetAuth, kFailure, kAuthErr)}},
9419 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9420 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9421 TestRound(kGetAuth, kSuccess, OK)}},
9422 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9423 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9424 TestRound(kGetAuth, kFailure, kAuthErr)}},
9425 // Non-Authenticating HTTPS server through an authenticating proxy.
9426 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9427 { TestRound(kConnect, kProxyChallenge, OK),
9428 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9429 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9430 { TestRound(kConnect, kProxyChallenge, OK),
9431 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9432 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9433 { TestRound(kConnect, kProxyChallenge, OK),
9434 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9435 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9436 { TestRound(kConnect, kProxyChallenge, OK),
9437 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9438 // Authenticating HTTPS server through an authenticating proxy.
9439 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9440 { TestRound(kConnect, kProxyChallenge, OK),
9441 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9442 &kGet, &kServerChallenge),
9443 TestRound(kGetAuth, kSuccess, OK)}},
9444 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9445 { TestRound(kConnect, kProxyChallenge, OK),
9446 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9447 &kGet, &kServerChallenge),
9448 TestRound(kGetAuth, kFailure, kAuthErr)}},
9449 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9450 { TestRound(kConnect, kProxyChallenge, OK),
9451 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9452 &kGet, &kServerChallenge),
9453 TestRound(kGetAuth, kSuccess, OK)}},
9454 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9455 { TestRound(kConnect, kProxyChallenge, OK),
9456 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9457 &kGet, &kServerChallenge),
9458 TestRound(kGetAuth, kFailure, kAuthErr)}},
9459 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9460 { TestRound(kConnect, kProxyChallenge, OK),
9461 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9462 &kGet, &kServerChallenge),
9463 TestRound(kGetAuth, kSuccess, OK)}},
9464 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9465 { TestRound(kConnect, kProxyChallenge, OK),
9466 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9467 &kGet, &kServerChallenge),
9468 TestRound(kGetAuth, kFailure, kAuthErr)}},
9469 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9470 { TestRound(kConnect, kProxyChallenge, OK),
9471 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9472 &kGet, &kServerChallenge),
9473 TestRound(kGetAuth, kSuccess, OK)}},
9474 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9475 { TestRound(kConnect, kProxyChallenge, OK),
9476 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9477 &kGet, &kServerChallenge),
9478 TestRound(kGetAuth, kFailure, kAuthErr)}},
9479 };
9480
[email protected]044de0642010-06-17 10:42:159481 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089482 HttpAuthHandlerMock::Factory* auth_factory(
9483 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079484 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159485 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269486
9487 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159488 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089489 for (int n = 0; n < 2; n++) {
9490 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9491 std::string auth_challenge = "Mock realm=proxy";
9492 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249493 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9494 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089495 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9496 origin, BoundNetLog());
9497 auth_handler->SetGenerateExpectation(
9498 test_config.proxy_auth_timing == AUTH_ASYNC,
9499 test_config.proxy_auth_rv);
9500 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9501 }
[email protected]044de0642010-06-17 10:42:159502 }
9503 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009504 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159505 std::string auth_challenge = "Mock realm=server";
9506 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249507 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9508 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159509 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9510 origin, BoundNetLog());
9511 auth_handler->SetGenerateExpectation(
9512 test_config.server_auth_timing == AUTH_ASYNC,
9513 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089514 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159515 }
9516 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079517 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129518 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159519 } else {
[email protected]bb88e1d32013-05-03 23:11:079520 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159521 }
9522
9523 HttpRequestInfo request;
9524 request.method = "GET";
9525 request.url = GURL(test_config.server_url);
9526 request.load_flags = 0;
9527
[email protected]bb88e1d32013-05-03 23:11:079528 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079529 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159530
9531 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9532 const TestRound& read_write_round = test_config.rounds[round];
9533
9534 // Set up expected reads and writes.
9535 MockRead reads[2];
9536 reads[0] = read_write_round.read;
9537 size_t length_reads = 1;
9538 if (read_write_round.extra_read) {
9539 reads[1] = *read_write_round.extra_read;
9540 length_reads = 2;
9541 }
9542
9543 MockWrite writes[2];
9544 writes[0] = read_write_round.write;
9545 size_t length_writes = 1;
9546 if (read_write_round.extra_write) {
9547 writes[1] = *read_write_round.extra_write;
9548 length_writes = 2;
9549 }
9550 StaticSocketDataProvider data_provider(
9551 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079552 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159553
9554 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069555 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159556 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079557 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159558 &ssl_socket_data_provider);
9559
9560 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419561 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159562 int rv;
9563 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419564 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159565 } else {
[email protected]49639fa2011-12-20 23:22:419566 rv = trans.RestartWithAuth(
9567 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159568 }
9569 if (rv == ERR_IO_PENDING)
9570 rv = callback.WaitForResult();
9571
9572 // Compare results with expected data.
9573 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509574 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159575 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509576 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159577 } else {
9578 EXPECT_TRUE(response == NULL);
9579 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9580 continue;
9581 }
9582 if (round + 1 < test_config.num_auth_rounds) {
9583 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9584 } else {
9585 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9586 }
9587 }
[email protected]e5ae96a2010-04-14 20:12:459588 }
9589}
9590
[email protected]23e482282013-06-14 16:08:029591TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149592 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149593 HttpAuthHandlerMock::Factory* auth_factory(
9594 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079595 session_deps_.http_auth_handler_factory.reset(auth_factory);
9596 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9597 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9598 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149599
9600 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9601 auth_handler->set_connection_based(true);
9602 std::string auth_challenge = "Mock realm=server";
9603 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:249604 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9605 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:149606 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9607 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089608 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149609
[email protected]c871bce92010-07-15 21:51:149610 int rv = OK;
9611 const HttpResponseInfo* response = NULL;
9612 HttpRequestInfo request;
9613 request.method = "GET";
9614 request.url = origin;
9615 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279616
[email protected]bb88e1d32013-05-03 23:11:079617 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109618
9619 // Use a TCP Socket Pool with only one connection per group. This is used
9620 // to validate that the TCP socket is not released to the pool between
9621 // each round of multi-round authentication.
9622 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289623 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9624 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109625 50, // Max sockets for pool
9626 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289627 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079628 session_deps_.host_resolver.get(),
9629 session_deps_.socket_factory.get(),
9630 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449631 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9632 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029633 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449634 session_peer.SetClientSocketPoolManager(
9635 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109636
[email protected]262eec82013-03-19 21:01:369637 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419639 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149640
9641 const MockWrite kGet(
9642 "GET / HTTP/1.1\r\n"
9643 "Host: www.example.com\r\n"
9644 "Connection: keep-alive\r\n\r\n");
9645 const MockWrite kGetAuth(
9646 "GET / HTTP/1.1\r\n"
9647 "Host: www.example.com\r\n"
9648 "Connection: keep-alive\r\n"
9649 "Authorization: auth_token\r\n\r\n");
9650
9651 const MockRead kServerChallenge(
9652 "HTTP/1.1 401 Unauthorized\r\n"
9653 "WWW-Authenticate: Mock realm=server\r\n"
9654 "Content-Type: text/html; charset=iso-8859-1\r\n"
9655 "Content-Length: 14\r\n\r\n"
9656 "Unauthorized\r\n");
9657 const MockRead kSuccess(
9658 "HTTP/1.1 200 OK\r\n"
9659 "Content-Type: text/html; charset=iso-8859-1\r\n"
9660 "Content-Length: 3\r\n\r\n"
9661 "Yes");
9662
9663 MockWrite writes[] = {
9664 // First round
9665 kGet,
9666 // Second round
9667 kGetAuth,
9668 // Third round
9669 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309670 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109671 kGetAuth,
9672 // Competing request
9673 kGet,
[email protected]c871bce92010-07-15 21:51:149674 };
9675 MockRead reads[] = {
9676 // First round
9677 kServerChallenge,
9678 // Second round
9679 kServerChallenge,
9680 // Third round
[email protected]eca50e122010-09-11 14:03:309681 kServerChallenge,
9682 // Fourth round
[email protected]c871bce92010-07-15 21:51:149683 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109684 // Competing response
9685 kSuccess,
[email protected]c871bce92010-07-15 21:51:149686 };
9687 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9688 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079689 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149690
[email protected]7ef4cbbb2011-02-06 11:19:109691 const char* const kSocketGroup = "www.example.com:80";
9692
9693 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149694 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419695 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149696 if (rv == ERR_IO_PENDING)
9697 rv = callback.WaitForResult();
9698 EXPECT_EQ(OK, rv);
9699 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509700 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149701 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289702 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149703
[email protected]7ef4cbbb2011-02-06 11:19:109704 // In between rounds, another request comes in for the same domain.
9705 // It should not be able to grab the TCP socket that trans has already
9706 // claimed.
9707 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509708 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419709 TestCompletionCallback callback_compete;
9710 rv = trans_compete->Start(
9711 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109712 EXPECT_EQ(ERR_IO_PENDING, rv);
9713 // callback_compete.WaitForResult at this point would stall forever,
9714 // since the HttpNetworkTransaction does not release the request back to
9715 // the pool until after authentication completes.
9716
9717 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149718 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419719 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149720 if (rv == ERR_IO_PENDING)
9721 rv = callback.WaitForResult();
9722 EXPECT_EQ(OK, rv);
9723 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509724 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149725 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289726 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149727
[email protected]7ef4cbbb2011-02-06 11:19:109728 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149729 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419730 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149731 if (rv == ERR_IO_PENDING)
9732 rv = callback.WaitForResult();
9733 EXPECT_EQ(OK, rv);
9734 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509735 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149736 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289737 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309738
[email protected]7ef4cbbb2011-02-06 11:19:109739 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309740 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419741 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309742 if (rv == ERR_IO_PENDING)
9743 rv = callback.WaitForResult();
9744 EXPECT_EQ(OK, rv);
9745 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509746 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309747 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289748 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109749
9750 // Read the body since the fourth round was successful. This will also
9751 // release the socket back to the pool.
9752 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509753 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109754 if (rv == ERR_IO_PENDING)
9755 rv = callback.WaitForResult();
9756 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509757 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109758 EXPECT_EQ(0, rv);
9759 // There are still 0 idle sockets, since the trans_compete transaction
9760 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289761 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109762
9763 // The competing request can now finish. Wait for the headers and then
9764 // read the body.
9765 rv = callback_compete.WaitForResult();
9766 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509767 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109768 if (rv == ERR_IO_PENDING)
9769 rv = callback.WaitForResult();
9770 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509771 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109772 EXPECT_EQ(0, rv);
9773
9774 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289775 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149776}
9777
[email protected]65041fa2010-05-21 06:56:539778// This tests the case that a request is issued via http instead of spdy after
9779// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029780TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389781 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169782 std::vector<NextProto> next_protos;
9783 next_protos.push_back(kProtoHTTP11);
9784 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539785 HttpRequestInfo request;
9786 request.method = "GET";
9787 request.url = GURL("https://www.google.com/");
9788 request.load_flags = 0;
9789
9790 MockWrite data_writes[] = {
9791 MockWrite("GET / HTTP/1.1\r\n"
9792 "Host: www.google.com\r\n"
9793 "Connection: keep-alive\r\n\r\n"),
9794 };
9795
[email protected]8a0fc822013-06-27 20:52:439796 std::string alternate_protocol_http_header =
9797 GetAlternateProtocolHttpHeader();
9798
[email protected]65041fa2010-05-21 06:56:539799 MockRead data_reads[] = {
9800 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439801 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539802 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069803 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539804 };
9805
[email protected]8ddf8322012-02-23 18:08:069806 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539807 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9808 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469809 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539810
[email protected]bb88e1d32013-05-03 23:11:079811 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539812
9813 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9814 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079815 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539816
[email protected]49639fa2011-12-20 23:22:419817 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539818
[email protected]bb88e1d32013-05-03 23:11:079819 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369820 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539822
[email protected]49639fa2011-12-20 23:22:419823 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539824
9825 EXPECT_EQ(ERR_IO_PENDING, rv);
9826 EXPECT_EQ(OK, callback.WaitForResult());
9827
9828 const HttpResponseInfo* response = trans->GetResponseInfo();
9829 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509830 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539831 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9832
9833 std::string response_data;
9834 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9835 EXPECT_EQ("hello world", response_data);
9836
9837 EXPECT_FALSE(response->was_fetched_via_spdy);
9838 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539839}
[email protected]26ef6582010-06-24 02:30:479840
[email protected]23e482282013-06-14 16:08:029841TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479842 // Simulate the SSL handshake completing with an NPN negotiation
9843 // followed by an immediate server closing of the socket.
9844 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389845 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039846 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479847
9848 HttpRequestInfo request;
9849 request.method = "GET";
9850 request.url = GURL("https://www.google.com/");
9851 request.load_flags = 0;
9852
[email protected]8ddf8322012-02-23 18:08:069853 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029854 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079855 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479856
[email protected]cdf8f7e72013-05-23 10:56:469857 scoped_ptr<SpdyFrame> req(
9858 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139859 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479860
9861 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069862 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479863 };
9864
[email protected]dd54bd82012-07-19 23:44:579865 DelayedSocketData spdy_data(
9866 0, // don't wait in this case, immediate hangup.
9867 spdy_reads, arraysize(spdy_reads),
9868 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079869 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479870
[email protected]49639fa2011-12-20 23:22:419871 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479872
[email protected]bb88e1d32013-05-03 23:11:079873 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369874 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479876
[email protected]49639fa2011-12-20 23:22:419877 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479878 EXPECT_EQ(ERR_IO_PENDING, rv);
9879 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479880}
[email protected]65d34382010-07-01 18:12:269881
[email protected]795cbf82013-07-22 09:37:279882// A subclass of HttpAuthHandlerMock that records the request URL when
9883// it gets it. This is needed since the auth handler may get destroyed
9884// before we get a chance to query it.
9885class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9886 public:
9887 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9888
9889 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9890
9891 protected:
9892 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9893 const HttpRequestInfo* request,
9894 const CompletionCallback& callback,
9895 std::string* auth_token) OVERRIDE {
9896 *url_ = request->url;
9897 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9898 credentials, request, callback, auth_token);
9899 }
9900
9901 private:
9902 GURL* url_;
9903};
9904
[email protected]23e482282013-06-14 16:08:029905TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309906 // This test ensures that the URL passed into the proxy is upgraded
9907 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389908 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439909 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309910
[email protected]bb88e1d32013-05-03 23:11:079911 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209912 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9913 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079914 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279915 GURL request_url;
9916 {
9917 HttpAuthHandlerMock::Factory* auth_factory =
9918 new HttpAuthHandlerMock::Factory();
9919 UrlRecordingHttpAuthHandlerMock* auth_handler =
9920 new UrlRecordingHttpAuthHandlerMock(&request_url);
9921 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9922 auth_factory->set_do_init_from_challenge(true);
9923 session_deps_.http_auth_handler_factory.reset(auth_factory);
9924 }
[email protected]f45c1ee2010-08-03 00:54:309925
9926 HttpRequestInfo request;
9927 request.method = "GET";
9928 request.url = GURL("http://www.google.com");
9929 request.load_flags = 0;
9930
9931 // First round goes unauthenticated through the proxy.
9932 MockWrite data_writes_1[] = {
9933 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9934 "Host: www.google.com\r\n"
9935 "Proxy-Connection: keep-alive\r\n"
9936 "\r\n"),
9937 };
9938 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069939 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309940 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239941 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309942 "Proxy-Connection: close\r\n"
9943 "\r\n"),
9944 };
9945 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9946 data_writes_1, arraysize(data_writes_1));
9947
9948 // Second round tries to tunnel to www.google.com due to the
9949 // Alternate-Protocol announcement in the first round. It fails due
9950 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599951 // After the failure, a tunnel is established to www.google.com using
9952 // Proxy-Authorization headers. There is then a SPDY request round.
9953 //
[email protected]fe3b7dc2012-02-03 19:52:099954 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9955 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9956 // does a Disconnect and Connect on the same socket, rather than trying
9957 // to obtain a new one.
9958 //
[email protected]394816e92010-08-03 07:38:599959 // NOTE: Originally, the proxy response to the second CONNECT request
9960 // simply returned another 407 so the unit test could skip the SSL connection
9961 // establishment and SPDY framing issues. Alas, the
9962 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309963 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599964
[email protected]cdf8f7e72013-05-23 10:56:469965 scoped_ptr<SpdyFrame> req(
9966 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029967 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9968 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309969
[email protected]394816e92010-08-03 07:38:599970 MockWrite data_writes_2[] = {
9971 // First connection attempt without Proxy-Authorization.
9972 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9973 "Host: www.google.com\r\n"
9974 "Proxy-Connection: keep-alive\r\n"
9975 "\r\n"),
9976
9977 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309978 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9979 "Host: www.google.com\r\n"
9980 "Proxy-Connection: keep-alive\r\n"
9981 "Proxy-Authorization: auth_token\r\n"
9982 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309983
[email protected]394816e92010-08-03 07:38:599984 // SPDY request
9985 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309986 };
[email protected]394816e92010-08-03 07:38:599987 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9988 "Proxy-Authenticate: Mock\r\n"
9989 "Proxy-Connection: close\r\n"
9990 "\r\n");
9991 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9992 MockRead data_reads_2[] = {
9993 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069994 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9995 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599996 arraysize(kRejectConnectResponse) - 1, 1),
9997
9998 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069999 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910000 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910001
10002 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910003 CreateMockRead(*resp.get(), 6),
10004 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610005 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910006 };
[email protected]dd54bd82012-07-19 23:44:5710007 OrderedSocketData data_2(
10008 data_reads_2, arraysize(data_reads_2),
10009 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010010
[email protected]8ddf8322012-02-23 18:08:0610011 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210012 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010013
[email protected]d973e99a2012-02-17 21:02:3610014 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510015 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10016 NULL, 0, NULL, 0);
10017 hanging_non_alternate_protocol_socket.set_connect_data(
10018 never_finishing_connect);
10019
[email protected]bb88e1d32013-05-03 23:11:0710020 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10021 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10022 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10023 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510024 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710025 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010026
10027 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110028 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610029 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110031 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010032 EXPECT_EQ(ERR_IO_PENDING, rv);
10033 EXPECT_EQ(OK, callback_1.WaitForResult());
10034
10035 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110036 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610037 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110039 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010040 EXPECT_EQ(ERR_IO_PENDING, rv);
10041 EXPECT_EQ(OK, callback_2.WaitForResult());
10042 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010043 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010044 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10045
10046 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110047 TestCompletionCallback callback_3;
10048 rv = trans_2->RestartWithAuth(
10049 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010050 EXPECT_EQ(ERR_IO_PENDING, rv);
10051 EXPECT_EQ(OK, callback_3.WaitForResult());
10052
10053 // After all that work, these two lines (or actually, just the scheme) are
10054 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010055 EXPECT_EQ("https", request_url.scheme());
10056 EXPECT_EQ("www.google.com", request_url.host());
10057
[email protected]029c83b62013-01-24 05:28:2010058 LoadTimingInfo load_timing_info;
10059 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10060 TestLoadTimingNotReusedWithPac(load_timing_info,
10061 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810062}
10063
10064// Test that if we cancel the transaction as the connection is completing, that
10065// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210066TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810067 // Setup everything about the connection to complete synchronously, so that
10068 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10069 // for is the callback from the HttpStreamRequest.
10070 // Then cancel the transaction.
10071 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610072 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810073 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610074 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10075 MockRead(SYNCHRONOUS, "hello world"),
10076 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810077 };
10078
[email protected]8e6441ca2010-08-19 05:56:3810079 HttpRequestInfo request;
10080 request.method = "GET";
10081 request.url = GURL("http://www.google.com/");
10082 request.load_flags = 0;
10083
[email protected]bb88e1d32013-05-03 23:11:0710084 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710085 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710086 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0710087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:2710088
[email protected]8e6441ca2010-08-19 05:56:3810089 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10090 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710091 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810092
[email protected]49639fa2011-12-20 23:22:4110093 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810094
[email protected]333bdf62012-06-08 22:57:2910095 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110096 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810097 EXPECT_EQ(ERR_IO_PENDING, rv);
10098 trans.reset(); // Cancel the transaction here.
10099
[email protected]2da659e2013-05-23 20:51:3410100 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010101}
10102
[email protected]76a505b2010-08-25 06:23:0010103// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210104TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710105 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010106 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910107 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710108 session_deps_.net_log = log.bound().net_log();
10109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010110
[email protected]76a505b2010-08-25 06:23:0010111 HttpRequestInfo request;
10112 request.method = "GET";
10113 request.url = GURL("http://www.google.com/");
10114
10115 MockWrite data_writes1[] = {
10116 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10117 "Host: www.google.com\r\n"
10118 "Proxy-Connection: keep-alive\r\n\r\n"),
10119 };
10120
10121 MockRead data_reads1[] = {
10122 MockRead("HTTP/1.1 200 OK\r\n"),
10123 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10124 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610125 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010126 };
10127
10128 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10129 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710130 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010131
[email protected]49639fa2011-12-20 23:22:4110132 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010133
[email protected]262eec82013-03-19 21:01:3610134 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010135 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010136
[email protected]49639fa2011-12-20 23:22:4110137 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010138 EXPECT_EQ(ERR_IO_PENDING, rv);
10139
10140 rv = callback1.WaitForResult();
10141 EXPECT_EQ(OK, rv);
10142
10143 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010144 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010145
10146 EXPECT_TRUE(response->headers->IsKeepAlive());
10147 EXPECT_EQ(200, response->headers->response_code());
10148 EXPECT_EQ(100, response->headers->GetContentLength());
10149 EXPECT_TRUE(response->was_fetched_via_proxy);
10150 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010151
10152 LoadTimingInfo load_timing_info;
10153 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10154 TestLoadTimingNotReusedWithPac(load_timing_info,
10155 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010156}
10157
10158// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210159TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710160 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010161 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910162 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710163 session_deps_.net_log = log.bound().net_log();
10164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010165
[email protected]76a505b2010-08-25 06:23:0010166 HttpRequestInfo request;
10167 request.method = "GET";
10168 request.url = GURL("https://www.google.com/");
10169
10170 // Since we have proxy, should try to establish tunnel.
10171 MockWrite data_writes1[] = {
10172 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10173 "Host: www.google.com\r\n"
10174 "Proxy-Connection: keep-alive\r\n\r\n"),
10175
10176 MockWrite("GET / HTTP/1.1\r\n"
10177 "Host: www.google.com\r\n"
10178 "Connection: keep-alive\r\n\r\n"),
10179 };
10180
10181 MockRead data_reads1[] = {
10182 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10183
10184 MockRead("HTTP/1.1 200 OK\r\n"),
10185 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10186 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610187 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010188 };
10189
10190 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10191 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710192 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610193 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710194 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010195
[email protected]49639fa2011-12-20 23:22:4110196 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010197
[email protected]262eec82013-03-19 21:01:3610198 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010200
[email protected]49639fa2011-12-20 23:22:4110201 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010202 EXPECT_EQ(ERR_IO_PENDING, rv);
10203
10204 rv = callback1.WaitForResult();
10205 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710206 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010207 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010208 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010209 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010210 NetLog::PHASE_NONE);
10211 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010212 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010213 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10214 NetLog::PHASE_NONE);
10215
10216 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010217 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010218
10219 EXPECT_TRUE(response->headers->IsKeepAlive());
10220 EXPECT_EQ(200, response->headers->response_code());
10221 EXPECT_EQ(100, response->headers->GetContentLength());
10222 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10223 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:2010224
10225 LoadTimingInfo load_timing_info;
10226 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10227 TestLoadTimingNotReusedWithPac(load_timing_info,
10228 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010229}
10230
10231// Test a basic HTTPS GET request through a proxy, but the server hangs up
10232// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210233TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710234 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910235 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710236 session_deps_.net_log = log.bound().net_log();
10237 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010238
[email protected]76a505b2010-08-25 06:23:0010239 HttpRequestInfo request;
10240 request.method = "GET";
10241 request.url = GURL("https://www.google.com/");
10242
10243 // Since we have proxy, should try to establish tunnel.
10244 MockWrite data_writes1[] = {
10245 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10246 "Host: www.google.com\r\n"
10247 "Proxy-Connection: keep-alive\r\n\r\n"),
10248
10249 MockWrite("GET / HTTP/1.1\r\n"
10250 "Host: www.google.com\r\n"
10251 "Connection: keep-alive\r\n\r\n"),
10252 };
10253
10254 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610255 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010256 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610257 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010258 };
10259
10260 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10261 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710262 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610263 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010265
[email protected]49639fa2011-12-20 23:22:4110266 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010267
[email protected]262eec82013-03-19 21:01:3610268 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010270
[email protected]49639fa2011-12-20 23:22:4110271 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010272 EXPECT_EQ(ERR_IO_PENDING, rv);
10273
10274 rv = callback1.WaitForResult();
10275 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710276 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010277 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010278 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010279 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010280 NetLog::PHASE_NONE);
10281 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010282 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010283 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10284 NetLog::PHASE_NONE);
10285}
10286
[email protected]749eefa82010-09-13 22:14:0310287// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210288TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610289 scoped_ptr<SpdyFrame> req(
10290 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310291 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10292
[email protected]23e482282013-06-14 16:08:0210293 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10294 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310295 MockRead spdy_reads[] = {
10296 CreateMockRead(*resp),
10297 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610298 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310299 };
10300
[email protected]dd54bd82012-07-19 23:44:5710301 DelayedSocketData spdy_data(
10302 1, // wait for one write to finish before reading.
10303 spdy_reads, arraysize(spdy_reads),
10304 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710305 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310306
[email protected]8ddf8322012-02-23 18:08:0610307 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210308 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310310
[email protected]bb88e1d32013-05-03 23:11:0710311 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310312
10313 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810314 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010315 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10316 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:2710317 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610318 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310319
10320 HttpRequestInfo request;
10321 request.method = "GET";
10322 request.url = GURL("https://www.google.com/");
10323 request.load_flags = 0;
10324
10325 // This is the important line that marks this as a preconnect.
10326 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10327
[email protected]262eec82013-03-19 21:01:3610328 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010329 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310330
[email protected]41d64e82013-07-03 22:44:2610331 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110332 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310333 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110334 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310335}
10336
[email protected]73b8dd222010-11-11 19:55:2410337// Given a net error, cause that error to be returned from the first Write()
10338// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210339void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710340 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710341 net::HttpRequestInfo request_info;
10342 request_info.url = GURL("https://www.example.com/");
10343 request_info.method = "GET";
10344 request_info.load_flags = net::LOAD_NORMAL;
10345
[email protected]8ddf8322012-02-23 18:08:0610346 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410347 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610348 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410349 };
10350 net::StaticSocketDataProvider data(NULL, 0,
10351 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710352 session_deps_.socket_factory->AddSocketDataProvider(&data);
10353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410354
[email protected]bb88e1d32013-05-03 23:11:0710355 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610356 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010357 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410358
[email protected]49639fa2011-12-20 23:22:4110359 TestCompletionCallback callback;
10360 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410361 if (rv == net::ERR_IO_PENDING)
10362 rv = callback.WaitForResult();
10363 ASSERT_EQ(error, rv);
10364}
10365
[email protected]23e482282013-06-14 16:08:0210366TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410367 // Just check a grab bag of cert errors.
10368 static const int kErrors[] = {
10369 ERR_CERT_COMMON_NAME_INVALID,
10370 ERR_CERT_AUTHORITY_INVALID,
10371 ERR_CERT_DATE_INVALID,
10372 };
10373 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610374 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10375 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410376 }
10377}
10378
[email protected]bd0b6772011-01-11 19:59:3010379// Ensure that a client certificate is removed from the SSL client auth
10380// cache when:
10381// 1) No proxy is involved.
10382// 2) TLS False Start is disabled.
10383// 3) The initial TLS handshake requests a client certificate.
10384// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210385TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310386 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710387 net::HttpRequestInfo request_info;
10388 request_info.url = GURL("https://www.example.com/");
10389 request_info.method = "GET";
10390 request_info.load_flags = net::LOAD_NORMAL;
10391
[email protected]bd0b6772011-01-11 19:59:3010392 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110393 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010394
10395 // [ssl_]data1 contains the data for the first SSL handshake. When a
10396 // CertificateRequest is received for the first time, the handshake will
10397 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610398 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010399 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710400 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010401 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710402 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010403
10404 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10405 // False Start is not being used, the result of the SSL handshake will be
10406 // returned as part of the SSLClientSocket::Connect() call. This test
10407 // matches the result of a server sending a handshake_failure alert,
10408 // rather than a Finished message, because it requires a client
10409 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610410 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010411 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010413 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010415
10416 // [ssl_]data3 contains the data for the third SSL handshake. When a
10417 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710418 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10419 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010420 // of the HttpNetworkTransaction. Because this test failure is due to
10421 // requiring a client certificate, this fallback handshake should also
10422 // fail.
[email protected]8ddf8322012-02-23 18:08:0610423 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010424 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710425 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010426 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710427 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010428
[email protected]80c75f682012-05-26 16:22:1710429 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10430 // connection to a server fails during an SSL handshake,
10431 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10432 // connection was attempted with TLSv1. This is transparent to the caller
10433 // of the HttpNetworkTransaction. Because this test failure is due to
10434 // requiring a client certificate, this fallback handshake should also
10435 // fail.
10436 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10437 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710439 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710440 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710441
[email protected]7799de12013-05-30 05:52:5110442 // Need one more if TLSv1.2 is enabled.
10443 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10444 ssl_data5.cert_request_info = cert_request.get();
10445 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10446 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10447 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10448
[email protected]bb88e1d32013-05-03 23:11:0710449 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610450 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010451 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010452
[email protected]bd0b6772011-01-11 19:59:3010453 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110454 TestCompletionCallback callback;
10455 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010456 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10457
10458 // Complete the SSL handshake, which should abort due to requiring a
10459 // client certificate.
10460 rv = callback.WaitForResult();
10461 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10462
10463 // Indicate that no certificate should be supplied. From the perspective
10464 // of SSLClientCertCache, NULL is just as meaningful as a real
10465 // certificate, so this is the same as supply a
10466 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110467 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010468 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10469
10470 // Ensure the certificate was added to the client auth cache before
10471 // allowing the connection to continue restarting.
10472 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110473 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10474 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010475 ASSERT_EQ(NULL, client_cert.get());
10476
10477 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710478 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10479 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010480 rv = callback.WaitForResult();
10481 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10482
10483 // Ensure that the client certificate is removed from the cache on a
10484 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110485 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10486 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010487}
10488
10489// Ensure that a client certificate is removed from the SSL client auth
10490// cache when:
10491// 1) No proxy is involved.
10492// 2) TLS False Start is enabled.
10493// 3) The initial TLS handshake requests a client certificate.
10494// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210495TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310496 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710497 net::HttpRequestInfo request_info;
10498 request_info.url = GURL("https://www.example.com/");
10499 request_info.method = "GET";
10500 request_info.load_flags = net::LOAD_NORMAL;
10501
[email protected]bd0b6772011-01-11 19:59:3010502 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110503 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010504
10505 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10506 // return successfully after reading up to the peer's Certificate message.
10507 // This is to allow the caller to call SSLClientSocket::Write(), which can
10508 // enqueue application data to be sent in the same packet as the
10509 // ChangeCipherSpec and Finished messages.
10510 // The actual handshake will be finished when SSLClientSocket::Read() is
10511 // called, which expects to process the peer's ChangeCipherSpec and
10512 // Finished messages. If there was an error negotiating with the peer,
10513 // such as due to the peer requiring a client certificate when none was
10514 // supplied, the alert sent by the peer won't be processed until Read() is
10515 // called.
10516
10517 // Like the non-False Start case, when a client certificate is requested by
10518 // the peer, the handshake is aborted during the Connect() call.
10519 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610520 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010521 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710522 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010523 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710524 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010525
10526 // When a client certificate is supplied, Connect() will not be aborted
10527 // when the peer requests the certificate. Instead, the handshake will
10528 // artificially succeed, allowing the caller to write the HTTP request to
10529 // the socket. The handshake messages are not processed until Read() is
10530 // called, which then detects that the handshake was aborted, due to the
10531 // peer sending a handshake_failure because it requires a client
10532 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610533 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010534 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710535 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010536 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610537 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010538 };
10539 net::StaticSocketDataProvider data2(
10540 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710541 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010542
10543 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710544 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10545 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610546 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010547 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710548 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010549 net::StaticSocketDataProvider data3(
10550 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710551 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010552
[email protected]80c75f682012-05-26 16:22:1710553 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10554 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10555 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10556 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710557 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710558 net::StaticSocketDataProvider data4(
10559 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710560 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710561
[email protected]7799de12013-05-30 05:52:5110562 // Need one more if TLSv1.2 is enabled.
10563 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10564 ssl_data5.cert_request_info = cert_request.get();
10565 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10566 net::StaticSocketDataProvider data5(
10567 data2_reads, arraysize(data2_reads), NULL, 0);
10568 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10569
[email protected]bb88e1d32013-05-03 23:11:0710570 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610571 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010572 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010573
[email protected]bd0b6772011-01-11 19:59:3010574 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110575 TestCompletionCallback callback;
10576 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010577 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10578
10579 // Complete the SSL handshake, which should abort due to requiring a
10580 // client certificate.
10581 rv = callback.WaitForResult();
10582 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10583
10584 // Indicate that no certificate should be supplied. From the perspective
10585 // of SSLClientCertCache, NULL is just as meaningful as a real
10586 // certificate, so this is the same as supply a
10587 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110588 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010589 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10590
10591 // Ensure the certificate was added to the client auth cache before
10592 // allowing the connection to continue restarting.
10593 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110594 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10595 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010596 ASSERT_EQ(NULL, client_cert.get());
10597
[email protected]bd0b6772011-01-11 19:59:3010598 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710599 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10600 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010601 rv = callback.WaitForResult();
10602 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10603
10604 // Ensure that the client certificate is removed from the cache on a
10605 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110606 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10607 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010608}
10609
[email protected]8c405132011-01-11 22:03:1810610// Ensure that a client certificate is removed from the SSL client auth
10611// cache when:
10612// 1) An HTTPS proxy is involved.
10613// 3) The HTTPS proxy requests a client certificate.
10614// 4) The client supplies an invalid/unacceptable certificate for the
10615// proxy.
10616// The test is repeated twice, first for connecting to an HTTPS endpoint,
10617// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210618TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710619 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810620 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910621 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710622 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810623
10624 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110625 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810626
10627 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10628 // [ssl_]data[1-3]. Rather than represending the endpoint
10629 // (www.example.com:443), they represent failures with the HTTPS proxy
10630 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610631 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810632 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810634 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710635 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810636
[email protected]8ddf8322012-02-23 18:08:0610637 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810638 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710639 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810640 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710641 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810642
[email protected]80c75f682012-05-26 16:22:1710643 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10644#if 0
[email protected]8ddf8322012-02-23 18:08:0610645 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810646 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710647 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810648 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710649 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710650#endif
[email protected]8c405132011-01-11 22:03:1810651
10652 net::HttpRequestInfo requests[2];
10653 requests[0].url = GURL("https://www.example.com/");
10654 requests[0].method = "GET";
10655 requests[0].load_flags = net::LOAD_NORMAL;
10656
10657 requests[1].url = GURL("http://www.example.com/");
10658 requests[1].method = "GET";
10659 requests[1].load_flags = net::LOAD_NORMAL;
10660
10661 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710662 session_deps_.socket_factory->ResetNextMockIndexes();
10663 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810664 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010665 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810666
10667 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110668 TestCompletionCallback callback;
10669 int rv = trans->Start(
10670 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810671 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10672
10673 // Complete the SSL handshake, which should abort due to requiring a
10674 // client certificate.
10675 rv = callback.WaitForResult();
10676 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10677
10678 // Indicate that no certificate should be supplied. From the perspective
10679 // of SSLClientCertCache, NULL is just as meaningful as a real
10680 // certificate, so this is the same as supply a
10681 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110682 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810683 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10684
10685 // Ensure the certificate was added to the client auth cache before
10686 // allowing the connection to continue restarting.
10687 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110688 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10689 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810690 ASSERT_EQ(NULL, client_cert.get());
10691 // Ensure the certificate was NOT cached for the endpoint. This only
10692 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110693 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10694 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810695
10696 // Restart the handshake. This will consume ssl_data2, which fails, and
10697 // then consume ssl_data3, which should also fail. The result code is
10698 // checked against what ssl_data3 should return.
10699 rv = callback.WaitForResult();
10700 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10701
10702 // Now that the new handshake has failed, ensure that the client
10703 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110704 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10705 HostPortPair("proxy", 70), &client_cert));
10706 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10707 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810708 }
10709}
10710
[email protected]23e482282013-06-14 16:08:0210711// Unlike TEST/TEST_F, which are macros that expand to further macros,
10712// TEST_P is a macro that expands directly to code that stringizes the
10713// arguments. As a result, macros passed as parameters (such as prefix
10714// or test_case_name) will not be expanded by the preprocessor. To
10715// work around this, indirect the macro for TEST_P, so that the
10716// pre-processor will expand macros such as MAYBE_test_name before
10717// instantiating the test.
10718#define WRAPPED_TEST_P(test_case_name, test_name) \
10719 TEST_P(test_case_name, test_name)
10720
[email protected]45b170822012-05-04 21:18:1410721// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10722#if defined(OS_WIN)
10723#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10724#else
10725#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10726#endif
[email protected]23e482282013-06-14 16:08:0210727WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610728 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310729 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610730
10731 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710732 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10733 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610734 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10735 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610736
[email protected]8ddf8322012-02-23 18:08:0610737 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210738 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610740
[email protected]cdf8f7e72013-05-23 10:56:4610741 scoped_ptr<SpdyFrame> host1_req(
10742 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10743 scoped_ptr<SpdyFrame> host2_req(
10744 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610745 MockWrite spdy_writes[] = {
10746 CreateMockWrite(*host1_req, 1),
10747 CreateMockWrite(*host2_req, 4),
10748 };
[email protected]23e482282013-06-14 16:08:0210749 scoped_ptr<SpdyFrame> host1_resp(
10750 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10751 scoped_ptr<SpdyFrame> host1_resp_body(
10752 spdy_util_.ConstructSpdyBodyFrame(1, true));
10753 scoped_ptr<SpdyFrame> host2_resp(
10754 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10755 scoped_ptr<SpdyFrame> host2_resp_body(
10756 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610757 MockRead spdy_reads[] = {
10758 CreateMockRead(*host1_resp, 2),
10759 CreateMockRead(*host1_resp_body, 3),
10760 CreateMockRead(*host2_resp, 5),
10761 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610762 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610763 };
10764
[email protected]d2b5f092012-06-08 23:55:0210765 IPAddressNumber ip;
10766 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10767 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10768 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710769 OrderedSocketData spdy_data(
10770 connect,
10771 spdy_reads, arraysize(spdy_reads),
10772 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710773 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610774
[email protected]aa22b242011-11-16 18:58:2910775 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610776 HttpRequestInfo request1;
10777 request1.method = "GET";
10778 request1.url = GURL("https://www.google.com/");
10779 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010780 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610781
[email protected]49639fa2011-12-20 23:22:4110782 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610783 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110784 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610785
10786 const HttpResponseInfo* response = trans1.GetResponseInfo();
10787 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010788 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610789 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10790
10791 std::string response_data;
10792 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10793 EXPECT_EQ("hello!", response_data);
10794
10795 // Preload www.gmail.com into HostCache.
10796 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010797 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610798 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010799 rv = session_deps_.host_resolver->Resolve(resolve_info,
10800 DEFAULT_PRIORITY,
10801 &ignored,
10802 callback.callback(),
10803 NULL,
10804 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710805 EXPECT_EQ(ERR_IO_PENDING, rv);
10806 rv = callback.WaitForResult();
10807 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610808
10809 HttpRequestInfo request2;
10810 request2.method = "GET";
10811 request2.url = GURL("https://www.gmail.com/");
10812 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010813 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610814
[email protected]49639fa2011-12-20 23:22:4110815 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610816 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110817 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610818
10819 response = trans2.GetResponseInfo();
10820 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010821 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610822 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10823 EXPECT_TRUE(response->was_fetched_via_spdy);
10824 EXPECT_TRUE(response->was_npn_negotiated);
10825 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10826 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610827}
[email protected]45b170822012-05-04 21:18:1410828#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610829
[email protected]23e482282013-06-14 16:08:0210830TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210831 HttpStreamFactory::set_use_alternate_protocols(true);
10832 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10833
10834 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710835 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10836 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210837 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10838 pool_peer.DisableDomainAuthenticationVerification();
10839
10840 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210841 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710842 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210843
[email protected]cdf8f7e72013-05-23 10:56:4610844 scoped_ptr<SpdyFrame> host1_req(
10845 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10846 scoped_ptr<SpdyFrame> host2_req(
10847 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210848 MockWrite spdy_writes[] = {
10849 CreateMockWrite(*host1_req, 1),
10850 CreateMockWrite(*host2_req, 4),
10851 };
[email protected]23e482282013-06-14 16:08:0210852 scoped_ptr<SpdyFrame> host1_resp(
10853 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10854 scoped_ptr<SpdyFrame> host1_resp_body(
10855 spdy_util_.ConstructSpdyBodyFrame(1, true));
10856 scoped_ptr<SpdyFrame> host2_resp(
10857 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10858 scoped_ptr<SpdyFrame> host2_resp_body(
10859 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210860 MockRead spdy_reads[] = {
10861 CreateMockRead(*host1_resp, 2),
10862 CreateMockRead(*host1_resp_body, 3),
10863 CreateMockRead(*host2_resp, 5),
10864 CreateMockRead(*host2_resp_body, 6),
10865 MockRead(ASYNC, 0, 7),
10866 };
10867
10868 IPAddressNumber ip;
10869 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10870 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10871 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710872 OrderedSocketData spdy_data(
10873 connect,
10874 spdy_reads, arraysize(spdy_reads),
10875 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710876 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210877
10878 TestCompletionCallback callback;
10879 HttpRequestInfo request1;
10880 request1.method = "GET";
10881 request1.url = GURL("https://www.google.com/");
10882 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010883 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210884
10885 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10886 EXPECT_EQ(ERR_IO_PENDING, rv);
10887 EXPECT_EQ(OK, callback.WaitForResult());
10888
10889 const HttpResponseInfo* response = trans1.GetResponseInfo();
10890 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010891 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210892 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10893
10894 std::string response_data;
10895 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10896 EXPECT_EQ("hello!", response_data);
10897
10898 HttpRequestInfo request2;
10899 request2.method = "GET";
10900 request2.url = GURL("https://www.gmail.com/");
10901 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010902 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210903
10904 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10905 EXPECT_EQ(ERR_IO_PENDING, rv);
10906 EXPECT_EQ(OK, callback.WaitForResult());
10907
10908 response = trans2.GetResponseInfo();
10909 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010910 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210911 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10912 EXPECT_TRUE(response->was_fetched_via_spdy);
10913 EXPECT_TRUE(response->was_npn_negotiated);
10914 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10915 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210916}
10917
[email protected]e3ceb682011-06-28 23:55:4610918class OneTimeCachingHostResolver : public net::HostResolver {
10919 public:
10920 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10921 : host_port_(host_port) {}
10922 virtual ~OneTimeCachingHostResolver() {}
10923
10924 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10925
10926 // HostResolver methods:
10927 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010928 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610929 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910930 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610931 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010932 const BoundNetLog& net_log) OVERRIDE {
10933 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010934 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010935 }
10936
10937 virtual int ResolveFromCache(const RequestInfo& info,
10938 AddressList* addresses,
10939 const BoundNetLog& net_log) OVERRIDE {
10940 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10941 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910942 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610943 return rv;
10944 }
10945
[email protected]95a214c2011-08-04 21:50:4010946 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610947 host_resolver_.CancelRequest(req);
10948 }
10949
[email protected]46da33be2011-07-19 21:58:0410950 MockCachingHostResolver* GetMockHostResolver() {
10951 return &host_resolver_;
10952 }
10953
[email protected]e3ceb682011-06-28 23:55:4610954 private:
10955 MockCachingHostResolver host_resolver_;
10956 const HostPortPair host_port_;
10957};
10958
[email protected]45b170822012-05-04 21:18:1410959// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10960#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710961#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10962 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410963#else
[email protected]bb88e1d32013-05-03 23:11:0710964#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10965 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410966#endif
[email protected]23e482282013-06-14 16:08:0210967WRAPPED_TEST_P(HttpNetworkTransactionTest,
10968 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210969// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10970// prefix doesn't work with parametrized tests).
10971#if defined(OS_WIN)
10972 return;
10973#endif
10974
[email protected]e3ceb682011-06-28 23:55:4610975 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310976 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610977
10978 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610979 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410980 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710981 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610982 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710983 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610984 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10985 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610986
[email protected]8ddf8322012-02-23 18:08:0610987 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210988 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710989 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610990
[email protected]cdf8f7e72013-05-23 10:56:4610991 scoped_ptr<SpdyFrame> host1_req(
10992 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10993 scoped_ptr<SpdyFrame> host2_req(
10994 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610995 MockWrite spdy_writes[] = {
10996 CreateMockWrite(*host1_req, 1),
10997 CreateMockWrite(*host2_req, 4),
10998 };
[email protected]23e482282013-06-14 16:08:0210999 scoped_ptr<SpdyFrame> host1_resp(
11000 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11001 scoped_ptr<SpdyFrame> host1_resp_body(
11002 spdy_util_.ConstructSpdyBodyFrame(1, true));
11003 scoped_ptr<SpdyFrame> host2_resp(
11004 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11005 scoped_ptr<SpdyFrame> host2_resp_body(
11006 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611007 MockRead spdy_reads[] = {
11008 CreateMockRead(*host1_resp, 2),
11009 CreateMockRead(*host1_resp_body, 3),
11010 CreateMockRead(*host2_resp, 5),
11011 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611012 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611013 };
11014
[email protected]d2b5f092012-06-08 23:55:0211015 IPAddressNumber ip;
11016 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11017 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11018 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711019 OrderedSocketData spdy_data(
11020 connect,
11021 spdy_reads, arraysize(spdy_reads),
11022 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711023 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611024
[email protected]aa22b242011-11-16 18:58:2911025 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611026 HttpRequestInfo request1;
11027 request1.method = "GET";
11028 request1.url = GURL("https://www.google.com/");
11029 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011030 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611031
[email protected]49639fa2011-12-20 23:22:4111032 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111034 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611035
11036 const HttpResponseInfo* response = trans1.GetResponseInfo();
11037 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011038 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611039 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11040
11041 std::string response_data;
11042 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11043 EXPECT_EQ("hello!", response_data);
11044
11045 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011046 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611047 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011048 rv = host_resolver.Resolve(resolve_info,
11049 DEFAULT_PRIORITY,
11050 &ignored,
11051 callback.callback(),
11052 NULL,
11053 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711054 EXPECT_EQ(ERR_IO_PENDING, rv);
11055 rv = callback.WaitForResult();
11056 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611057
11058 HttpRequestInfo request2;
11059 request2.method = "GET";
11060 request2.url = GURL("https://www.gmail.com/");
11061 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011062 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611063
[email protected]49639fa2011-12-20 23:22:4111064 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611065 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111066 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611067
11068 response = trans2.GetResponseInfo();
11069 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011070 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611071 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11072 EXPECT_TRUE(response->was_fetched_via_spdy);
11073 EXPECT_TRUE(response->was_npn_negotiated);
11074 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11075 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611076}
[email protected]45b170822012-05-04 21:18:1411077#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611078
[email protected]23e482282013-06-14 16:08:0211079TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2911080 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611081 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2911082 };
11083 MockRead data_reads2[] = {
11084 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11085 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611086 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2911087 };
11088 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
11089 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
11090 StaticSocketDataProvider* data[] = { &data1, &data2 };
11091
11092 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
11093
11094 EXPECT_EQ(OK, out.rv);
11095 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
11096 EXPECT_EQ("hello world", out.response_data);
11097}
11098
[email protected]23e482282013-06-14 16:08:0211099TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2911100 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0611101 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2911102 };
11103 MockWrite data_writes2[] = {
11104 MockWrite("GET / HTTP/1.1\r\n"
11105 "Host: www.google.com\r\n"
11106 "Connection: keep-alive\r\n\r\n"),
11107 };
11108 MockRead data_reads2[] = {
11109 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11110 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611111 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2911112 };
11113 StaticSocketDataProvider data1(NULL, 0,
11114 data_writes1, arraysize(data_writes1));
11115 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
11116 data_writes2, arraysize(data_writes2));
11117 StaticSocketDataProvider* data[] = { &data1, &data2 };
11118
11119 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
11120
11121 EXPECT_EQ(OK, out.rv);
11122 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
11123 EXPECT_EQ("hello world", out.response_data);
11124}
11125
[email protected]23e482282013-06-14 16:08:0211126TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0411127 const std::string https_url = "https://www.google.com/";
11128 const std::string http_url = "http://www.google.com:443/";
11129
11130 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611131 scoped_ptr<SpdyFrame> req1(
11132 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411133
11134 MockWrite writes1[] = {
11135 CreateMockWrite(*req1, 0),
11136 };
11137
[email protected]23e482282013-06-14 16:08:0211138 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11139 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411140 MockRead reads1[] = {
11141 CreateMockRead(*resp1, 1),
11142 CreateMockRead(*body1, 2),
11143 MockRead(ASYNC, ERR_IO_PENDING, 3)
11144 };
11145
[email protected]dd54bd82012-07-19 23:44:5711146 DelayedSocketData data1(
11147 1, reads1, arraysize(reads1),
11148 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411149 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711150 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411151
11152 // HTTP GET for the HTTP URL
11153 MockWrite writes2[] = {
11154 MockWrite(ASYNC, 4,
11155 "GET / HTTP/1.1\r\n"
11156 "Host: www.google.com:443\r\n"
11157 "Connection: keep-alive\r\n\r\n"),
11158 };
11159
11160 MockRead reads2[] = {
11161 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11162 MockRead(ASYNC, 6, "hello"),
11163 MockRead(ASYNC, 7, OK),
11164 };
11165
[email protected]dd54bd82012-07-19 23:44:5711166 DelayedSocketData data2(
11167 1, reads2, arraysize(reads2),
11168 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411169
[email protected]8450d722012-07-02 19:14:0411170 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211171 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11173 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11174 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411175
[email protected]bb88e1d32013-05-03 23:11:0711176 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411177
11178 // Start the first transaction to set up the SpdySession
11179 HttpRequestInfo request1;
11180 request1.method = "GET";
11181 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411182 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011183 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411184 TestCompletionCallback callback1;
11185 EXPECT_EQ(ERR_IO_PENDING,
11186 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411187 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411188
11189 EXPECT_EQ(OK, callback1.WaitForResult());
11190 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11191
11192 // Now, start the HTTP request
11193 HttpRequestInfo request2;
11194 request2.method = "GET";
11195 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411196 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011197 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411198 TestCompletionCallback callback2;
11199 EXPECT_EQ(ERR_IO_PENDING,
11200 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411201 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411202
11203 EXPECT_EQ(OK, callback2.WaitForResult());
11204 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11205}
11206
[email protected]23e482282013-06-14 16:08:0211207TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0411208 const std::string https_url = "https://www.google.com/";
11209 const std::string http_url = "http://www.google.com:443/";
11210
11211 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5411212 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11213 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611214 scoped_ptr<SpdyFrame> req1(
11215 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411216
11217 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0211218 scoped_ptr<SpdyFrame> wrapped_req1(
11219 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0411220 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0211221 spdy_util_.GetMethodKey(), "GET",
11222 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
11223 spdy_util_.GetHostKey(), "www.google.com:443",
11224 spdy_util_.GetSchemeKey(), "http",
11225 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0411226 };
[email protected]4bd46222013-05-14 19:32:2311227 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
11228 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
11229 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0411230
11231 MockWrite writes1[] = {
11232 CreateMockWrite(*connect, 0),
11233 CreateMockWrite(*wrapped_req1, 2),
11234 CreateMockWrite(*req2, 5),
11235 };
11236
[email protected]23e482282013-06-14 16:08:0211237 scoped_ptr<SpdyFrame> conn_resp(
11238 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11239 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11240 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11241 scoped_ptr<SpdyFrame> wrapped_resp1(
11242 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11243 scoped_ptr<SpdyFrame> wrapped_body1(
11244 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11245 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11246 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411247 MockRead reads1[] = {
11248 CreateMockRead(*conn_resp, 1),
11249 CreateMockRead(*wrapped_resp1, 3),
11250 CreateMockRead(*wrapped_body1, 4),
11251 CreateMockRead(*resp2, 6),
11252 CreateMockRead(*body2, 7),
11253 MockRead(ASYNC, ERR_IO_PENDING, 8)
11254 };
11255
[email protected]dd54bd82012-07-19 23:44:5711256 DeterministicSocketData data1(reads1, arraysize(reads1),
11257 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411258 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711259 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411260
[email protected]bb88e1d32013-05-03 23:11:0711261 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211262 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11263 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711264 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411265 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211266 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711267 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411268 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211269 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711270 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11271 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411272
11273 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711274 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411275
11276 // Start the first transaction to set up the SpdySession
11277 HttpRequestInfo request1;
11278 request1.method = "GET";
11279 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411280 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011281 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411282 TestCompletionCallback callback1;
11283 EXPECT_EQ(ERR_IO_PENDING,
11284 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411285 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711286 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411287
11288 EXPECT_EQ(OK, callback1.WaitForResult());
11289 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11290
[email protected]f6c63db52013-02-02 00:35:2211291 LoadTimingInfo load_timing_info1;
11292 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11293 TestLoadTimingNotReusedWithPac(load_timing_info1,
11294 CONNECT_TIMING_HAS_SSL_TIMES);
11295
[email protected]8450d722012-07-02 19:14:0411296 // Now, start the HTTP request
11297 HttpRequestInfo request2;
11298 request2.method = "GET";
11299 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411300 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011301 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411302 TestCompletionCallback callback2;
11303 EXPECT_EQ(ERR_IO_PENDING,
11304 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411305 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711306 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411307
11308 EXPECT_EQ(OK, callback2.WaitForResult());
11309 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211310
11311 LoadTimingInfo load_timing_info2;
11312 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11313 // The established SPDY sessions is considered reused by the HTTP request.
11314 TestLoadTimingReusedWithPac(load_timing_info2);
11315 // HTTP requests over a SPDY session should have a different connection
11316 // socket_log_id than requests over a tunnel.
11317 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411318}
11319
[email protected]23e482282013-06-14 16:08:0211320TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411321 HttpStreamFactory::set_force_spdy_always(true);
11322 const std::string https_url = "https://www.google.com/";
11323 const std::string http_url = "http://www.google.com:443/";
11324
11325 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611326 scoped_ptr<SpdyFrame> req1(
11327 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411328 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611329 scoped_ptr<SpdyFrame> req2(
11330 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411331
11332 MockWrite writes[] = {
11333 CreateMockWrite(*req1, 1),
11334 CreateMockWrite(*req2, 4),
11335 };
11336
[email protected]23e482282013-06-14 16:08:0211337 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11338 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11339 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11340 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411341 MockRead reads[] = {
11342 CreateMockRead(*resp1, 2),
11343 CreateMockRead(*body1, 3),
11344 CreateMockRead(*resp2, 5),
11345 CreateMockRead(*body2, 6),
11346 MockRead(ASYNC, ERR_IO_PENDING, 7)
11347 };
11348
[email protected]dd54bd82012-07-19 23:44:5711349 OrderedSocketData data(reads, arraysize(reads),
11350 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411351
[email protected]8450d722012-07-02 19:14:0411352 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211353 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11355 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411356
[email protected]bb88e1d32013-05-03 23:11:0711357 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411358
11359 // Start the first transaction to set up the SpdySession
11360 HttpRequestInfo request1;
11361 request1.method = "GET";
11362 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411363 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011364 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411365 TestCompletionCallback callback1;
11366 EXPECT_EQ(ERR_IO_PENDING,
11367 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411368 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411369
11370 EXPECT_EQ(OK, callback1.WaitForResult());
11371 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11372
11373 // Now, start the HTTP request
11374 HttpRequestInfo request2;
11375 request2.method = "GET";
11376 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411377 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011378 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411379 TestCompletionCallback callback2;
11380 EXPECT_EQ(ERR_IO_PENDING,
11381 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411382 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411383
11384 EXPECT_EQ(OK, callback2.WaitForResult());
11385 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11386}
11387
[email protected]2d88e7d2012-07-19 17:55:1711388// Test that in the case where we have a SPDY session to a SPDY proxy
11389// that we do not pool other origins that resolve to the same IP when
11390// the certificate does not match the new origin.
11391// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211392TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711393 const std::string url1 = "http://www.google.com/";
11394 const std::string url2 = "https://mail.google.com/";
11395 const std::string ip_addr = "1.2.3.4";
11396
11397 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211398 scoped_ptr<SpdyHeaderBlock> headers(
11399 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311400 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211401 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711402
11403 MockWrite writes1[] = {
11404 CreateMockWrite(*req1, 0),
11405 };
11406
[email protected]23e482282013-06-14 16:08:0211407 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11408 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711409 MockRead reads1[] = {
11410 CreateMockRead(*resp1, 1),
11411 CreateMockRead(*body1, 2),
11412 MockRead(ASYNC, OK, 3) // EOF
11413 };
11414
11415 scoped_ptr<DeterministicSocketData> data1(
11416 new DeterministicSocketData(reads1, arraysize(reads1),
11417 writes1, arraysize(writes1)));
11418 IPAddressNumber ip;
11419 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11420 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11421 MockConnect connect_data1(ASYNC, OK, peer_addr);
11422 data1->set_connect_data(connect_data1);
11423
11424 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611425 scoped_ptr<SpdyFrame> req2(
11426 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711427
11428 MockWrite writes2[] = {
11429 CreateMockWrite(*req2, 0),
11430 };
11431
[email protected]23e482282013-06-14 16:08:0211432 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11433 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711434 MockRead reads2[] = {
11435 CreateMockRead(*resp2, 1),
11436 CreateMockRead(*body2, 2),
11437 MockRead(ASYNC, OK, 3) // EOF
11438 };
11439
11440 scoped_ptr<DeterministicSocketData> data2(
11441 new DeterministicSocketData(reads2, arraysize(reads2),
11442 writes2, arraysize(writes2)));
11443 MockConnect connect_data2(ASYNC, OK);
11444 data2->set_connect_data(connect_data2);
11445
11446 // Set up a proxy config that sends HTTP requests to a proxy, and
11447 // all others direct.
11448 ProxyConfig proxy_config;
11449 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11450 CapturingProxyResolver* capturing_proxy_resolver =
11451 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711452 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711453 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11454 NULL));
11455
11456 // Load a valid cert. Note, that this does not need to
11457 // be valid for proxy because the MockSSLClientSocket does
11458 // not actually verify it. But SpdySession will use this
11459 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511460 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711461 scoped_refptr<X509Certificate> server_cert(
11462 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11463 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11464
11465 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211466 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711467 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711468 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11469 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11470 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711471
11472 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211473 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711474 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11475 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11476 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711477
[email protected]bb88e1d32013-05-03 23:11:0711478 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11479 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11480 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711481
11482 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711483 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711484
11485 // Start the first transaction to set up the SpdySession
11486 HttpRequestInfo request1;
11487 request1.method = "GET";
11488 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711489 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011490 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711491 TestCompletionCallback callback1;
11492 ASSERT_EQ(ERR_IO_PENDING,
11493 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11494 data1->RunFor(3);
11495
11496 ASSERT_TRUE(callback1.have_result());
11497 EXPECT_EQ(OK, callback1.WaitForResult());
11498 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11499
11500 // Now, start the HTTP request
11501 HttpRequestInfo request2;
11502 request2.method = "GET";
11503 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711504 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011505 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711506 TestCompletionCallback callback2;
11507 EXPECT_EQ(ERR_IO_PENDING,
11508 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411509 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711510 data2->RunFor(3);
11511
11512 ASSERT_TRUE(callback2.have_result());
11513 EXPECT_EQ(OK, callback2.WaitForResult());
11514 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11515}
11516
[email protected]85f97342013-04-17 06:12:2411517// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11518// error) in SPDY session, removes the socket from pool and closes the SPDY
11519// session. Verify that new url's from the same HttpNetworkSession (and a new
11520// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211521TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411522 const std::string https_url = "https://www.google.com/";
11523
11524 MockRead reads1[] = {
11525 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11526 };
11527
11528 scoped_ptr<DeterministicSocketData> data1(
11529 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11530 data1->SetStop(1);
11531
[email protected]cdf8f7e72013-05-23 10:56:4611532 scoped_ptr<SpdyFrame> req2(
11533 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411534 MockWrite writes2[] = {
11535 CreateMockWrite(*req2, 0),
11536 };
11537
[email protected]23e482282013-06-14 16:08:0211538 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11539 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411540 MockRead reads2[] = {
11541 CreateMockRead(*resp2, 1),
11542 CreateMockRead(*body2, 2),
11543 MockRead(ASYNC, OK, 3) // EOF
11544 };
11545
11546 scoped_ptr<DeterministicSocketData> data2(
11547 new DeterministicSocketData(reads2, arraysize(reads2),
11548 writes2, arraysize(writes2)));
11549
[email protected]85f97342013-04-17 06:12:2411550 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211551 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711552 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11553 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11554 data1.get());
[email protected]85f97342013-04-17 06:12:2411555
11556 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211557 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711558 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11559 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11560 data2.get());
[email protected]85f97342013-04-17 06:12:2411561
11562 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711563 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411564
11565 // Start the first transaction to set up the SpdySession and verify that
11566 // connection was closed.
11567 HttpRequestInfo request1;
11568 request1.method = "GET";
11569 request1.url = GURL(https_url);
11570 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011571 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411572 TestCompletionCallback callback1;
11573 EXPECT_EQ(ERR_IO_PENDING,
11574 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411575 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411576 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11577
11578 // Now, start the second request and make sure it succeeds.
11579 HttpRequestInfo request2;
11580 request2.method = "GET";
11581 request2.url = GURL(https_url);
11582 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011583 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411584 TestCompletionCallback callback2;
11585 EXPECT_EQ(ERR_IO_PENDING,
11586 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411587 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411588 data2->RunFor(3);
11589
11590 ASSERT_TRUE(callback2.have_result());
11591 EXPECT_EQ(OK, callback2.WaitForResult());
11592 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11593}
11594
[email protected]23e482282013-06-14 16:08:0211595TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311596 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11597 ClientSocketPoolManager::set_max_sockets_per_group(
11598 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11599 ClientSocketPoolManager::set_max_sockets_per_pool(
11600 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11601
11602 // Use two different hosts with different IPs so they don't get pooled.
11603 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11604 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11605 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11606
11607 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211608 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311609 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211610 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11613
[email protected]cdf8f7e72013-05-23 10:56:4611614 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311615 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11616 MockWrite spdy1_writes[] = {
11617 CreateMockWrite(*host1_req, 1),
11618 };
[email protected]23e482282013-06-14 16:08:0211619 scoped_ptr<SpdyFrame> host1_resp(
11620 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11621 scoped_ptr<SpdyFrame> host1_resp_body(
11622 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311623 MockRead spdy1_reads[] = {
11624 CreateMockRead(*host1_resp, 2),
11625 CreateMockRead(*host1_resp_body, 3),
11626 MockRead(ASYNC, ERR_IO_PENDING, 4),
11627 };
11628
11629 scoped_ptr<OrderedSocketData> spdy1_data(
11630 new OrderedSocketData(
11631 spdy1_reads, arraysize(spdy1_reads),
11632 spdy1_writes, arraysize(spdy1_writes)));
11633 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11634
[email protected]cdf8f7e72013-05-23 10:56:4611635 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311636 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11637 MockWrite spdy2_writes[] = {
11638 CreateMockWrite(*host2_req, 1),
11639 };
[email protected]23e482282013-06-14 16:08:0211640 scoped_ptr<SpdyFrame> host2_resp(
11641 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11642 scoped_ptr<SpdyFrame> host2_resp_body(
11643 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311644 MockRead spdy2_reads[] = {
11645 CreateMockRead(*host2_resp, 2),
11646 CreateMockRead(*host2_resp_body, 3),
11647 MockRead(ASYNC, ERR_IO_PENDING, 4),
11648 };
11649
11650 scoped_ptr<OrderedSocketData> spdy2_data(
11651 new OrderedSocketData(
11652 spdy2_reads, arraysize(spdy2_reads),
11653 spdy2_writes, arraysize(spdy2_writes)));
11654 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11655
11656 MockWrite http_write[] = {
11657 MockWrite("GET / HTTP/1.1\r\n"
11658 "Host: www.a.com\r\n"
11659 "Connection: keep-alive\r\n\r\n"),
11660 };
11661
11662 MockRead http_read[] = {
11663 MockRead("HTTP/1.1 200 OK\r\n"),
11664 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11665 MockRead("Content-Length: 6\r\n\r\n"),
11666 MockRead("hello!"),
11667 };
11668 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11669 http_write, arraysize(http_write));
11670 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11671
11672 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011673 SpdySessionKey spdy_session_key_a(
11674 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311675 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611676 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311677
11678 TestCompletionCallback callback;
11679 HttpRequestInfo request1;
11680 request1.method = "GET";
11681 request1.url = GURL("https://www.a.com/");
11682 request1.load_flags = 0;
11683 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311685
11686 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11687 EXPECT_EQ(ERR_IO_PENDING, rv);
11688 EXPECT_EQ(OK, callback.WaitForResult());
11689
11690 const HttpResponseInfo* response = trans->GetResponseInfo();
11691 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011692 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311693 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11694 EXPECT_TRUE(response->was_fetched_via_spdy);
11695 EXPECT_TRUE(response->was_npn_negotiated);
11696
11697 std::string response_data;
11698 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11699 EXPECT_EQ("hello!", response_data);
11700 trans.reset();
11701 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611702 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311703
11704 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011705 SpdySessionKey spdy_session_key_b(
11706 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311707 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611708 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311709 HttpRequestInfo request2;
11710 request2.method = "GET";
11711 request2.url = GURL("https://www.b.com/");
11712 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011713 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311714
11715 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11716 EXPECT_EQ(ERR_IO_PENDING, rv);
11717 EXPECT_EQ(OK, callback.WaitForResult());
11718
11719 response = trans->GetResponseInfo();
11720 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011721 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311722 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11723 EXPECT_TRUE(response->was_fetched_via_spdy);
11724 EXPECT_TRUE(response->was_npn_negotiated);
11725 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11726 EXPECT_EQ("hello!", response_data);
11727 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611728 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311729 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611730 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311731
11732 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011733 SpdySessionKey spdy_session_key_a1(
11734 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311735 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611736 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311737 HttpRequestInfo request3;
11738 request3.method = "GET";
11739 request3.url = GURL("http://www.a.com/");
11740 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011741 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311742
11743 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11744 EXPECT_EQ(ERR_IO_PENDING, rv);
11745 EXPECT_EQ(OK, callback.WaitForResult());
11746
11747 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_FALSE(response->was_fetched_via_spdy);
11752 EXPECT_FALSE(response->was_npn_negotiated);
11753 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11754 EXPECT_EQ("hello!", response_data);
11755 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611756 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311757 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611758 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311759}
11760
[email protected]79e1fd62013-06-20 06:50:0411761TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11762 HttpRequestInfo request;
11763 request.method = "GET";
11764 request.url = GURL("http://www.google.com/");
11765 request.load_flags = 0;
11766
[email protected]3fe8d2f82013-10-17 08:56:0711767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411768 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711769 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411770
11771 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11772 StaticSocketDataProvider data;
11773 data.set_connect_data(mock_connect);
11774 session_deps_.socket_factory->AddSocketDataProvider(&data);
11775
11776 TestCompletionCallback callback;
11777
11778 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11779 EXPECT_EQ(ERR_IO_PENDING, rv);
11780
11781 rv = callback.WaitForResult();
11782 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11783
11784 EXPECT_EQ(NULL, trans->GetResponseInfo());
11785
11786 // We don't care whether this succeeds or fails, but it shouldn't crash.
11787 HttpRequestHeaders request_headers;
11788 trans->GetFullRequestHeaders(&request_headers);
11789}
11790
11791TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11792 HttpRequestInfo request;
11793 request.method = "GET";
11794 request.url = GURL("http://www.google.com/");
11795 request.load_flags = 0;
11796
[email protected]3fe8d2f82013-10-17 08:56:0711797 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411798 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411800
11801 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11802 StaticSocketDataProvider data;
11803 data.set_connect_data(mock_connect);
11804 session_deps_.socket_factory->AddSocketDataProvider(&data);
11805
11806 TestCompletionCallback callback;
11807
11808 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11809 EXPECT_EQ(ERR_IO_PENDING, rv);
11810
11811 rv = callback.WaitForResult();
11812 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11813
11814 EXPECT_EQ(NULL, trans->GetResponseInfo());
11815
11816 // We don't care whether this succeeds or fails, but it shouldn't crash.
11817 HttpRequestHeaders request_headers;
11818 trans->GetFullRequestHeaders(&request_headers);
11819}
11820
11821TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11822 HttpRequestInfo request;
11823 request.method = "GET";
11824 request.url = GURL("http://www.google.com/");
11825 request.load_flags = 0;
11826
[email protected]3fe8d2f82013-10-17 08:56:0711827 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411828 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711829 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411830
11831 MockWrite data_writes[] = {
11832 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11833 };
11834 MockRead data_reads[] = {
11835 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11836 };
11837
11838 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11839 data_writes, arraysize(data_writes));
11840 session_deps_.socket_factory->AddSocketDataProvider(&data);
11841
11842 TestCompletionCallback callback;
11843
11844 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11845 EXPECT_EQ(ERR_IO_PENDING, rv);
11846
11847 rv = callback.WaitForResult();
11848 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11849
11850 EXPECT_EQ(NULL, trans->GetResponseInfo());
11851
11852 HttpRequestHeaders request_headers;
11853 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11854 EXPECT_TRUE(request_headers.HasHeader("Host"));
11855}
11856
11857TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11858 HttpRequestInfo request;
11859 request.method = "GET";
11860 request.url = GURL("http://www.google.com/");
11861 request.load_flags = 0;
11862
[email protected]3fe8d2f82013-10-17 08:56:0711863 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411864 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711865 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411866
11867 MockWrite data_writes[] = {
11868 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11869 };
11870 MockRead data_reads[] = {
11871 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11872 };
11873
11874 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11875 data_writes, arraysize(data_writes));
11876 session_deps_.socket_factory->AddSocketDataProvider(&data);
11877
11878 TestCompletionCallback callback;
11879
11880 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11881 EXPECT_EQ(ERR_IO_PENDING, rv);
11882
11883 rv = callback.WaitForResult();
11884 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11885
11886 EXPECT_EQ(NULL, trans->GetResponseInfo());
11887
11888 HttpRequestHeaders request_headers;
11889 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11890 EXPECT_TRUE(request_headers.HasHeader("Host"));
11891}
11892
11893TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11894 HttpRequestInfo request;
11895 request.method = "GET";
11896 request.url = GURL("http://www.google.com/");
11897 request.load_flags = 0;
11898
[email protected]3fe8d2f82013-10-17 08:56:0711899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411900 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411902
11903 MockWrite data_writes[] = {
11904 MockWrite("GET / HTTP/1.1\r\n"
11905 "Host: www.google.com\r\n"
11906 "Connection: keep-alive\r\n\r\n"),
11907 };
11908 MockRead data_reads[] = {
11909 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11910 };
11911
11912 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11913 data_writes, arraysize(data_writes));
11914 session_deps_.socket_factory->AddSocketDataProvider(&data);
11915
11916 TestCompletionCallback callback;
11917
11918 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11919 EXPECT_EQ(ERR_IO_PENDING, rv);
11920
11921 rv = callback.WaitForResult();
11922 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11923
11924 EXPECT_EQ(NULL, trans->GetResponseInfo());
11925
11926 HttpRequestHeaders request_headers;
11927 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11928 EXPECT_TRUE(request_headers.HasHeader("Host"));
11929}
11930
11931TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11932 HttpRequestInfo request;
11933 request.method = "GET";
11934 request.url = GURL("http://www.google.com/");
11935 request.load_flags = 0;
11936
[email protected]3fe8d2f82013-10-17 08:56:0711937 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411938 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711939 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411940
11941 MockWrite data_writes[] = {
11942 MockWrite("GET / HTTP/1.1\r\n"
11943 "Host: www.google.com\r\n"
11944 "Connection: keep-alive\r\n\r\n"),
11945 };
11946 MockRead data_reads[] = {
11947 MockRead(ASYNC, ERR_CONNECTION_RESET),
11948 };
11949
11950 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11951 data_writes, arraysize(data_writes));
11952 session_deps_.socket_factory->AddSocketDataProvider(&data);
11953
11954 TestCompletionCallback callback;
11955
11956 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11957 EXPECT_EQ(ERR_IO_PENDING, rv);
11958
11959 rv = callback.WaitForResult();
11960 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11961
11962 EXPECT_EQ(NULL, trans->GetResponseInfo());
11963
11964 HttpRequestHeaders request_headers;
11965 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11966 EXPECT_TRUE(request_headers.HasHeader("Host"));
11967}
11968
11969TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11970 HttpRequestInfo request;
11971 request.method = "GET";
11972 request.url = GURL("http://www.google.com/");
11973 request.load_flags = 0;
11974 request.extra_headers.SetHeader("X-Foo", "bar");
11975
[email protected]3fe8d2f82013-10-17 08:56:0711976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411977 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411979
11980 MockWrite data_writes[] = {
11981 MockWrite("GET / HTTP/1.1\r\n"
11982 "Host: www.google.com\r\n"
11983 "Connection: keep-alive\r\n"
11984 "X-Foo: bar\r\n\r\n"),
11985 };
11986 MockRead data_reads[] = {
11987 MockRead("HTTP/1.1 200 OK\r\n"
11988 "Content-Length: 5\r\n\r\n"
11989 "hello"),
11990 MockRead(ASYNC, ERR_UNEXPECTED),
11991 };
11992
11993 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11994 data_writes, arraysize(data_writes));
11995 session_deps_.socket_factory->AddSocketDataProvider(&data);
11996
11997 TestCompletionCallback callback;
11998
11999 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12000 EXPECT_EQ(ERR_IO_PENDING, rv);
12001
12002 rv = callback.WaitForResult();
12003 EXPECT_EQ(OK, rv);
12004
12005 HttpRequestHeaders request_headers;
12006 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12007 std::string foo;
12008 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12009 EXPECT_EQ("bar", foo);
12010}
12011
[email protected]bf828982013-08-14 18:01:4712012namespace {
12013
[email protected]e86839fd2013-08-14 18:29:0312014// Fake HttpStreamBase that simply records calls to SetPriority().
12015class FakeStream : public HttpStreamBase,
12016 public base::SupportsWeakPtr<FakeStream> {
12017 public:
12018 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
12019 virtual ~FakeStream() {}
12020
12021 RequestPriority priority() const { return priority_; }
12022
12023 virtual int InitializeStream(const HttpRequestInfo* request_info,
12024 RequestPriority priority,
12025 const BoundNetLog& net_log,
12026 const CompletionCallback& callback) OVERRIDE {
12027 return ERR_IO_PENDING;
12028 }
12029
12030 virtual int SendRequest(const HttpRequestHeaders& request_headers,
12031 HttpResponseInfo* response,
12032 const CompletionCallback& callback) OVERRIDE {
12033 ADD_FAILURE();
12034 return ERR_UNEXPECTED;
12035 }
12036
12037 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
12038 ADD_FAILURE();
12039 return ERR_UNEXPECTED;
12040 }
12041
12042 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
12043 ADD_FAILURE();
12044 return NULL;
12045 }
12046
12047 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
12048 const CompletionCallback& callback) OVERRIDE {
12049 ADD_FAILURE();
12050 return ERR_UNEXPECTED;
12051 }
12052
12053 virtual void Close(bool not_reusable) OVERRIDE {}
12054
12055 virtual bool IsResponseBodyComplete() const OVERRIDE {
12056 ADD_FAILURE();
12057 return false;
12058 }
12059
12060 virtual bool CanFindEndOfResponse() const OVERRIDE {
12061 return false;
12062 }
12063
12064 virtual bool IsConnectionReused() const OVERRIDE {
12065 ADD_FAILURE();
12066 return false;
12067 }
12068
12069 virtual void SetConnectionReused() OVERRIDE {
12070 ADD_FAILURE();
12071 }
12072
12073 virtual bool IsConnectionReusable() const OVERRIDE {
12074 ADD_FAILURE();
12075 return false;
12076 }
12077
[email protected]bc92bc972013-12-13 08:32:5912078 virtual int64 GetTotalReceivedBytes() const OVERRIDE {
12079 ADD_FAILURE();
12080 return 0;
12081 }
12082
[email protected]e86839fd2013-08-14 18:29:0312083 virtual bool GetLoadTimingInfo(
12084 LoadTimingInfo* load_timing_info) const OVERRIDE {
12085 ADD_FAILURE();
12086 return false;
12087 }
12088
12089 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
12090 ADD_FAILURE();
12091 }
12092
12093 virtual void GetSSLCertRequestInfo(
12094 SSLCertRequestInfo* cert_request_info) OVERRIDE {
12095 ADD_FAILURE();
12096 }
12097
12098 virtual bool IsSpdyHttpStream() const OVERRIDE {
12099 ADD_FAILURE();
12100 return false;
12101 }
12102
12103 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
12104 ADD_FAILURE();
12105 }
12106
12107 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12108 priority_ = priority;
12109 }
12110
12111 private:
12112 RequestPriority priority_;
12113
12114 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12115};
12116
12117// Fake HttpStreamRequest that simply records calls to SetPriority()
12118// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712119class FakeStreamRequest : public HttpStreamRequest,
12120 public base::SupportsWeakPtr<FakeStreamRequest> {
12121 public:
[email protected]e86839fd2013-08-14 18:29:0312122 FakeStreamRequest(RequestPriority priority,
12123 HttpStreamRequest::Delegate* delegate)
12124 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412125 delegate_(delegate),
12126 websocket_stream_create_helper_(NULL) {}
12127
12128 FakeStreamRequest(RequestPriority priority,
12129 HttpStreamRequest::Delegate* delegate,
12130 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12131 : priority_(priority),
12132 delegate_(delegate),
12133 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312134
[email protected]bf828982013-08-14 18:01:4712135 virtual ~FakeStreamRequest() {}
12136
12137 RequestPriority priority() const { return priority_; }
12138
[email protected]831e4a32013-11-14 02:14:4412139 const WebSocketHandshakeStreamBase::CreateHelper*
12140 websocket_stream_create_helper() const {
12141 return websocket_stream_create_helper_;
12142 }
12143
[email protected]e86839fd2013-08-14 18:29:0312144 // Create a new FakeStream and pass it to the request's
12145 // delegate. Returns a weak pointer to the FakeStream.
12146 base::WeakPtr<FakeStream> FinishStreamRequest() {
12147 FakeStream* fake_stream = new FakeStream(priority_);
12148 // Do this before calling OnStreamReady() as OnStreamReady() may
12149 // immediately delete |fake_stream|.
12150 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12151 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12152 return weak_stream;
12153 }
12154
[email protected]bf828982013-08-14 18:01:4712155 virtual int RestartTunnelWithProxyAuth(
12156 const AuthCredentials& credentials) OVERRIDE {
12157 ADD_FAILURE();
12158 return ERR_UNEXPECTED;
12159 }
12160
12161 virtual LoadState GetLoadState() const OVERRIDE {
12162 ADD_FAILURE();
12163 return LoadState();
12164 }
12165
12166 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12167 priority_ = priority;
12168 }
12169
12170 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712171 return false;
12172 }
12173
12174 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712175 return kProtoUnknown;
12176 }
12177
12178 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712179 return false;
12180 }
12181
12182 private:
12183 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312184 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412185 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712186
12187 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12188};
12189
12190// Fake HttpStreamFactory that vends FakeStreamRequests.
12191class FakeStreamFactory : public HttpStreamFactory {
12192 public:
12193 FakeStreamFactory() {}
12194 virtual ~FakeStreamFactory() {}
12195
12196 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12197 // RequestStream() (which may be NULL if it was destroyed already).
12198 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12199 return last_stream_request_;
12200 }
12201
12202 virtual HttpStreamRequest* RequestStream(
12203 const HttpRequestInfo& info,
12204 RequestPriority priority,
12205 const SSLConfig& server_ssl_config,
12206 const SSLConfig& proxy_ssl_config,
12207 HttpStreamRequest::Delegate* delegate,
12208 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0312209 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712210 last_stream_request_ = fake_request->AsWeakPtr();
12211 return fake_request;
12212 }
12213
[email protected]a9cf2b92013-10-30 12:08:4912214 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712215 const HttpRequestInfo& info,
12216 RequestPriority priority,
12217 const SSLConfig& server_ssl_config,
12218 const SSLConfig& proxy_ssl_config,
12219 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612220 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4712221 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4412222 FakeStreamRequest* fake_request =
12223 new FakeStreamRequest(priority, delegate, create_helper);
12224 last_stream_request_ = fake_request->AsWeakPtr();
12225 return fake_request;
[email protected]bf828982013-08-14 18:01:4712226 }
12227
12228 virtual void PreconnectStreams(int num_streams,
12229 const HttpRequestInfo& info,
12230 RequestPriority priority,
12231 const SSLConfig& server_ssl_config,
12232 const SSLConfig& proxy_ssl_config) OVERRIDE {
12233 ADD_FAILURE();
12234 }
12235
12236 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
12237 ADD_FAILURE();
12238 return NULL;
12239 }
12240
12241 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12242 ADD_FAILURE();
12243 return NULL;
12244 }
12245
12246 private:
12247 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12248
12249 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12250};
12251
[email protected]831e4a32013-11-14 02:14:4412252// TODO(yhirano): Split this class out into a net/websockets file, if it is
12253// worth doing.
12254class FakeWebSocketStreamCreateHelper :
12255 public WebSocketHandshakeStreamBase::CreateHelper {
12256 public:
12257 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112258 scoped_ptr<ClientSocketHandle> connection,
[email protected]831e4a32013-11-14 02:14:4412259 bool using_proxy) OVERRIDE {
12260 NOTREACHED();
12261 return NULL;
12262 }
12263
12264 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12265 const base::WeakPtr<SpdySession>& session,
12266 bool use_relative_url) OVERRIDE {
12267 NOTREACHED();
12268 return NULL;
12269 };
12270
12271 virtual ~FakeWebSocketStreamCreateHelper() {}
12272
12273 virtual scoped_ptr<WebSocketStream> Upgrade() {
12274 NOTREACHED();
12275 return scoped_ptr<WebSocketStream>();
12276 }
12277};
12278
[email protected]bf828982013-08-14 18:01:4712279} // namespace
12280
12281// Make sure that HttpNetworkTransaction passes on its priority to its
12282// stream request on start.
12283TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12284 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12285 HttpNetworkSessionPeer peer(session);
12286 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412287 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712288
12289 HttpNetworkTransaction trans(LOW, session);
12290
12291 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12292
12293 HttpRequestInfo request;
12294 TestCompletionCallback callback;
12295 EXPECT_EQ(ERR_IO_PENDING,
12296 trans.Start(&request, callback.callback(), BoundNetLog()));
12297
12298 base::WeakPtr<FakeStreamRequest> fake_request =
12299 fake_factory->last_stream_request();
12300 ASSERT_TRUE(fake_request != NULL);
12301 EXPECT_EQ(LOW, fake_request->priority());
12302}
12303
12304// Make sure that HttpNetworkTransaction passes on its priority
12305// updates to its stream request.
12306TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12307 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12308 HttpNetworkSessionPeer peer(session);
12309 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412310 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712311
12312 HttpNetworkTransaction trans(LOW, session);
12313
12314 HttpRequestInfo request;
12315 TestCompletionCallback callback;
12316 EXPECT_EQ(ERR_IO_PENDING,
12317 trans.Start(&request, callback.callback(), BoundNetLog()));
12318
12319 base::WeakPtr<FakeStreamRequest> fake_request =
12320 fake_factory->last_stream_request();
12321 ASSERT_TRUE(fake_request != NULL);
12322 EXPECT_EQ(LOW, fake_request->priority());
12323
12324 trans.SetPriority(LOWEST);
12325 ASSERT_TRUE(fake_request != NULL);
12326 EXPECT_EQ(LOWEST, fake_request->priority());
12327}
12328
[email protected]e86839fd2013-08-14 18:29:0312329// Make sure that HttpNetworkTransaction passes on its priority
12330// updates to its stream.
12331TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12333 HttpNetworkSessionPeer peer(session);
12334 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412335 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312336
12337 HttpNetworkTransaction trans(LOW, session);
12338
12339 HttpRequestInfo request;
12340 TestCompletionCallback callback;
12341 EXPECT_EQ(ERR_IO_PENDING,
12342 trans.Start(&request, callback.callback(), BoundNetLog()));
12343
12344 base::WeakPtr<FakeStreamRequest> fake_request =
12345 fake_factory->last_stream_request();
12346 ASSERT_TRUE(fake_request != NULL);
12347 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12348 ASSERT_TRUE(fake_stream != NULL);
12349 EXPECT_EQ(LOW, fake_stream->priority());
12350
12351 trans.SetPriority(LOWEST);
12352 EXPECT_EQ(LOWEST, fake_stream->priority());
12353}
12354
[email protected]831e4a32013-11-14 02:14:4412355TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12356 // The same logic needs to be tested for both ws: and wss: schemes, but this
12357 // test is already parameterised on NextProto, so it uses a loop to verify
12358 // that the different schemes work.
12359 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12360 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12361 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12362 HttpNetworkSessionPeer peer(session);
12363 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12364 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312365 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412366 scoped_ptr<HttpStreamFactory>(fake_factory));
12367
12368 HttpNetworkTransaction trans(LOW, session);
12369 trans.SetWebSocketHandshakeStreamCreateHelper(
12370 &websocket_stream_create_helper);
12371
12372 HttpRequestInfo request;
12373 TestCompletionCallback callback;
12374 request.method = "GET";
12375 request.url = GURL(test_cases[i]);
12376
12377 EXPECT_EQ(ERR_IO_PENDING,
12378 trans.Start(&request, callback.callback(), BoundNetLog()));
12379
12380 base::WeakPtr<FakeStreamRequest> fake_request =
12381 fake_factory->last_stream_request();
12382 ASSERT_TRUE(fake_request != NULL);
12383 EXPECT_EQ(&websocket_stream_create_helper,
12384 fake_request->websocket_stream_create_helper());
12385 }
12386}
12387
[email protected]043b68c82013-08-22 23:41:5212388// Tests that when a used socket is returned to the SSL socket pool, it's closed
12389// if the transport socket pool is stalled on the global socket limit.
12390TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12391 ClientSocketPoolManager::set_max_sockets_per_group(
12392 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12393 ClientSocketPoolManager::set_max_sockets_per_pool(
12394 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12395
12396 // Set up SSL request.
12397
12398 HttpRequestInfo ssl_request;
12399 ssl_request.method = "GET";
12400 ssl_request.url = GURL("https://www.google.com/");
12401
12402 MockWrite ssl_writes[] = {
12403 MockWrite("GET / HTTP/1.1\r\n"
12404 "Host: www.google.com\r\n"
12405 "Connection: keep-alive\r\n\r\n"),
12406 };
12407 MockRead ssl_reads[] = {
12408 MockRead("HTTP/1.1 200 OK\r\n"),
12409 MockRead("Content-Length: 11\r\n\r\n"),
12410 MockRead("hello world"),
12411 MockRead(SYNCHRONOUS, OK),
12412 };
12413 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12414 ssl_writes, arraysize(ssl_writes));
12415 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12416
12417 SSLSocketDataProvider ssl(ASYNC, OK);
12418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12419
12420 // Set up HTTP request.
12421
12422 HttpRequestInfo http_request;
12423 http_request.method = "GET";
12424 http_request.url = GURL("http://www.google.com/");
12425
12426 MockWrite http_writes[] = {
12427 MockWrite("GET / HTTP/1.1\r\n"
12428 "Host: www.google.com\r\n"
12429 "Connection: keep-alive\r\n\r\n"),
12430 };
12431 MockRead http_reads[] = {
12432 MockRead("HTTP/1.1 200 OK\r\n"),
12433 MockRead("Content-Length: 7\r\n\r\n"),
12434 MockRead("falafel"),
12435 MockRead(SYNCHRONOUS, OK),
12436 };
12437 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12438 http_writes, arraysize(http_writes));
12439 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12440
12441 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12442
12443 // Start the SSL request.
12444 TestCompletionCallback ssl_callback;
12445 scoped_ptr<HttpTransaction> ssl_trans(
12446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12447 ASSERT_EQ(ERR_IO_PENDING,
12448 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12449 BoundNetLog()));
12450
12451 // Start the HTTP request. Pool should stall.
12452 TestCompletionCallback http_callback;
12453 scoped_ptr<HttpTransaction> http_trans(
12454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12455 ASSERT_EQ(ERR_IO_PENDING,
12456 http_trans->Start(&http_request, http_callback.callback(),
12457 BoundNetLog()));
12458 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12459
12460 // Wait for response from SSL request.
12461 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12462 std::string response_data;
12463 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12464 EXPECT_EQ("hello world", response_data);
12465
12466 // The SSL socket should automatically be closed, so the HTTP request can
12467 // start.
12468 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12469 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12470
12471 // The HTTP request can now complete.
12472 ASSERT_EQ(OK, http_callback.WaitForResult());
12473 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12474 EXPECT_EQ("falafel", response_data);
12475
12476 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12477}
12478
12479// Tests that when a SSL connection is established but there's no corresponding
12480// request that needs it, the new socket is closed if the transport socket pool
12481// is stalled on the global socket limit.
12482TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12483 ClientSocketPoolManager::set_max_sockets_per_group(
12484 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12485 ClientSocketPoolManager::set_max_sockets_per_pool(
12486 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12487
12488 // Set up an ssl request.
12489
12490 HttpRequestInfo ssl_request;
12491 ssl_request.method = "GET";
12492 ssl_request.url = GURL("https://www.foopy.com/");
12493
12494 // No data will be sent on the SSL socket.
12495 StaticSocketDataProvider ssl_data;
12496 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12497
12498 SSLSocketDataProvider ssl(ASYNC, OK);
12499 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12500
12501 // Set up HTTP request.
12502
12503 HttpRequestInfo http_request;
12504 http_request.method = "GET";
12505 http_request.url = GURL("http://www.google.com/");
12506
12507 MockWrite http_writes[] = {
12508 MockWrite("GET / HTTP/1.1\r\n"
12509 "Host: www.google.com\r\n"
12510 "Connection: keep-alive\r\n\r\n"),
12511 };
12512 MockRead http_reads[] = {
12513 MockRead("HTTP/1.1 200 OK\r\n"),
12514 MockRead("Content-Length: 7\r\n\r\n"),
12515 MockRead("falafel"),
12516 MockRead(SYNCHRONOUS, OK),
12517 };
12518 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12519 http_writes, arraysize(http_writes));
12520 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12521
12522 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12523
12524 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12525 // cancelled when a normal transaction is cancelled.
12526 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12527 net::SSLConfig ssl_config;
12528 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12529 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12530 ssl_config, ssl_config);
12531 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12532
12533 // Start the HTTP request. Pool should stall.
12534 TestCompletionCallback http_callback;
12535 scoped_ptr<HttpTransaction> http_trans(
12536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12537 ASSERT_EQ(ERR_IO_PENDING,
12538 http_trans->Start(&http_request, http_callback.callback(),
12539 BoundNetLog()));
12540 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12541
12542 // The SSL connection will automatically be closed once the connection is
12543 // established, to let the HTTP request start.
12544 ASSERT_EQ(OK, http_callback.WaitForResult());
12545 std::string response_data;
12546 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12547 EXPECT_EQ("falafel", response_data);
12548
12549 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12550}
12551
[email protected]89ceba9a2009-03-21 03:46:0612552} // namespace net