blob: 00295419b930c9fe48b6d7640ca838ec66833ddf [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]125ef482013-06-11 18:32:4719#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0520#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3321#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3522#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1223#include "net/base/capturing_net_log.h"
[email protected]bacff652009-03-31 17:50:3324#include "net/base/completion_callback.h"
[email protected]58e32bb2013-01-21 18:23:2525#include "net/base/load_timing_info.h"
26#include "net/base/load_timing_info_test_util.h"
[email protected]169d0012010-05-10 23:20:1227#include "net/base/net_log.h"
28#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3129#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5230#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4031#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0632#include "net/base/upload_bytes_element_reader.h"
[email protected]329b68b2012-11-14 17:54:2733#include "net/base/upload_data_stream.h"
[email protected]d98961652012-09-11 20:27:2134#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1135#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1636#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5337#include "net/dns/mock_host_resolver.h"
[email protected]3c32c5f2010-05-18 15:18:1238#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0039#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2940#include "net/http/http_auth_handler_ntlm.h"
[email protected]0877e3d2009-10-17 22:29:5741#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5242#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5643#include "net/http/http_network_session_peer.h"
[email protected]17291a022011-10-10 07:32:5344#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5745#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3846#include "net/http/http_stream_factory.h"
initial.commit586acc5fe2008-07-26 22:42:5247#include "net/http/http_transaction_unittest.h"
[email protected]51fff29d2008-12-19 22:17:5348#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0349#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1150#include "net/proxy/proxy_resolver.h"
51#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4452#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0353#include "net/socket/client_socket_pool_manager.h"
[email protected]a42dbd142011-11-17 16:42:0254#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0755#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4456#include "net/socket/socket_test_util.h"
57#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5458#include "net/spdy/spdy_framer.h"
59#include "net/spdy/spdy_session.h"
60#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0261#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5762#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0363#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5764#include "net/ssl/ssl_config_service_defaults.h"
65#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1166#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4467#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5268#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1569#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2770#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5271
72//-----------------------------------------------------------------------------
73
[email protected]13c8a092010-07-29 06:15:4474namespace {
75
[email protected]42cba2fb2013-03-29 19:58:5776const base::string16 kBar(ASCIIToUTF16("bar"));
77const base::string16 kBar2(ASCIIToUTF16("bar2"));
78const base::string16 kBar3(ASCIIToUTF16("bar3"));
79const base::string16 kBaz(ASCIIToUTF16("baz"));
80const base::string16 kFirst(ASCIIToUTF16("first"));
81const base::string16 kFoo(ASCIIToUTF16("foo"));
82const base::string16 kFoo2(ASCIIToUTF16("foo2"));
83const base::string16 kFoo3(ASCIIToUTF16("foo3"));
84const base::string16 kFou(ASCIIToUTF16("fou"));
85const base::string16 kSecond(ASCIIToUTF16("second"));
86const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
87const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4488
[email protected]e5c026642012-03-17 00:14:0289int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
90 return session->GetTransportSocketPool(
91 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
92}
93
94int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
95 return session->GetSSLSocketPool(
96 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
97}
98
[email protected]043b68c82013-08-22 23:41:5299bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
100 return session->GetTransportSocketPool(
101 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
102}
103
[email protected]f3da152d2012-06-02 01:00:57104// Takes in a Value created from a NetLogHttpResponseParameter, and returns
105// a JSONified list of headers as a single string. Uses single quotes instead
106// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27107bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57108 if (!params)
109 return false;
[email protected]ea5ef4c2013-06-13 22:50:27110 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57111 if (!params->GetList("headers", &header_list))
112 return false;
113 std::string double_quote_headers;
114 base::JSONWriter::Write(header_list, &double_quote_headers);
115 ReplaceChars(double_quote_headers, "\"", "'", headers);
116 return true;
117}
118
[email protected]029c83b62013-01-24 05:28:20119// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
120// used.
121void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
122 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25123 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
124
[email protected]029c83b62013-01-24 05:28:20125 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
126 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
127
128 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
129 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25130
131 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25132
[email protected]3b23a222013-05-15 21:33:25133 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25134 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
135 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25136 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25137}
138
[email protected]029c83b62013-01-24 05:28:20139// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
140// used.
[email protected]58e32bb2013-01-21 18:23:25141void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
142 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20143 EXPECT_FALSE(load_timing_info.socket_reused);
144 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
145
146 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
147 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
148
149 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25150 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20151 EXPECT_LE(load_timing_info.connect_timing.connect_end,
152 load_timing_info.send_start);
153
154 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20155
[email protected]3b23a222013-05-15 21:33:25156 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20157 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
158 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25159 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20160}
161
162// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
163// used.
164void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
165 EXPECT_TRUE(load_timing_info.socket_reused);
166 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
167
168 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
169
170 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
171 EXPECT_LE(load_timing_info.proxy_resolve_start,
172 load_timing_info.proxy_resolve_end);
173 EXPECT_LE(load_timing_info.proxy_resolve_end,
174 load_timing_info.send_start);
175 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20176
[email protected]3b23a222013-05-15 21:33:25177 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20178 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
179 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25180 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20181}
182
183// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
184// used.
185void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
186 int connect_timing_flags) {
187 EXPECT_FALSE(load_timing_info.socket_reused);
188 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
189
190 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
191 EXPECT_LE(load_timing_info.proxy_resolve_start,
192 load_timing_info.proxy_resolve_end);
193 EXPECT_LE(load_timing_info.proxy_resolve_end,
194 load_timing_info.connect_timing.connect_start);
195 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
196 connect_timing_flags);
197 EXPECT_LE(load_timing_info.connect_timing.connect_end,
198 load_timing_info.send_start);
199
200 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20201
[email protected]3b23a222013-05-15 21:33:25202 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20203 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
204 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25205 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25206}
207
[email protected]13c8a092010-07-29 06:15:44208} // namespace
209
[email protected]89ceba9a2009-03-21 03:46:06210namespace net {
211
[email protected]448d4ca52012-03-04 04:12:23212namespace {
213
[email protected]c6bf8152012-12-02 07:43:34214HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
215 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14216}
217
[email protected]448d4ca52012-03-04 04:12:23218} // namespace
219
[email protected]23e482282013-06-14 16:08:02220class HttpNetworkTransactionTest
221 : public PlatformTest,
222 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03223 public:
[email protected]23e482282013-06-14 16:08:02224 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03225 // Important to restore the per-pool limit first, since the pool limit must
226 // always be greater than group limit, and the tests reduce both limits.
227 ClientSocketPoolManager::set_max_sockets_per_pool(
228 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
229 ClientSocketPoolManager::set_max_sockets_per_group(
230 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
231 }
232
[email protected]e3ceb682011-06-28 23:55:46233 protected:
[email protected]23e482282013-06-14 16:08:02234 HttpNetworkTransactionTest()
235 : spdy_util_(GetParam()),
236 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03237 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
238 HttpNetworkSession::NORMAL_SOCKET_POOL)),
239 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
240 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
241 }
[email protected]bb88e1d32013-05-03 23:11:07242
[email protected]e3ceb682011-06-28 23:55:46243 struct SimpleGetHelperResult {
244 int rv;
245 std::string status_line;
246 std::string response_data;
[email protected]58e32bb2013-01-21 18:23:25247 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46248 };
249
[email protected]2ff8b312010-04-26 22:20:54250 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50251 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34252 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54253 }
254
[email protected]0e75a732008-10-16 20:36:09255 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50256 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34257 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09258 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34259 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09260 PlatformTest::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]c54c6962013-02-01 04:53:19263 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:16264 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]0e75a732008-10-16 20:36:09265 }
266
[email protected]8a0fc822013-06-27 20:52:43267 // This is the expected return from a current server advertising SPDY.
268 std::string GetAlternateProtocolHttpHeader() {
269 return
270 std::string("Alternate-Protocol: 443:") +
271 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
272 "\r\n\r\n";
273 }
274
[email protected]202965992011-12-07 23:04:51275 // Either |write_failure| specifies a write failure or |read_failure|
276 // specifies a read failure when using a reused socket. In either case, the
277 // failure should cause the network transaction to resend the request, and the
278 // other argument should be NULL.
279 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
280 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52281
[email protected]5a60c8b2011-10-19 20:14:29282 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
283 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15284 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52285
[email protected]ff007e162009-05-23 09:13:15286 HttpRequestInfo request;
287 request.method = "GET";
288 request.url = GURL("http://www.google.com/");
289 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52290
[email protected]58e32bb2013-01-21 18:23:25291 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07292 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07293 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27294 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27296
[email protected]5a60c8b2011-10-19 20:14:29297 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07298 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29299 }
initial.commit586acc5fe2008-07-26 22:42:52300
[email protected]49639fa2011-12-20 23:22:41301 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52302
[email protected]3deb9a52010-11-11 00:24:40303 EXPECT_TRUE(log.bound().IsLoggingAllEvents());
[email protected]49639fa2011-12-20 23:22:41304 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15305 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52306
[email protected]ff007e162009-05-23 09:13:15307 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25308
309 // Even in the failure cases that use this function, connections are always
310 // successfully established before the error.
311 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
312 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
313
[email protected]ff007e162009-05-23 09:13:15314 if (out.rv != OK)
315 return out;
316
317 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50318 // Can't use ASSERT_* inside helper functions like this, so
319 // return an error.
[email protected]90499482013-06-01 00:39:50320 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50321 out.rv = ERR_UNEXPECTED;
322 return out;
323 }
[email protected]ff007e162009-05-23 09:13:15324 out.status_line = response->headers->GetStatusLine();
325
[email protected]80a09a82012-11-16 17:40:06326 EXPECT_EQ("127.0.0.1", response->socket_address.host());
327 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19328
[email protected]ff007e162009-05-23 09:13:15329 rv = ReadTransaction(trans.get(), &out.response_data);
330 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40331
[email protected]f3da152d2012-06-02 01:00:57332 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40333 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39334 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40335 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12336 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39337 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40338 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39339 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
340 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15341
[email protected]f3da152d2012-06-02 01:00:57342 std::string line;
343 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
344 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
345
[email protected]79e1fd62013-06-20 06:50:04346 HttpRequestHeaders request_headers;
347 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
348 std::string value;
349 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
350 EXPECT_EQ("www.google.com", value);
351 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
352 EXPECT_EQ("keep-alive", value);
353
354 std::string response_headers;
355 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
356 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
357 response_headers);
[email protected]3deb9a52010-11-11 00:24:40358
[email protected]aecfbf22008-10-16 02:02:47359 return out;
[email protected]ff007e162009-05-23 09:13:15360 }
initial.commit586acc5fe2008-07-26 22:42:52361
[email protected]5a60c8b2011-10-19 20:14:29362 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
363 size_t reads_count) {
364 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
365 StaticSocketDataProvider* data[] = { &reads };
366 return SimpleGetHelperForData(data, 1);
367 }
368
[email protected]ff007e162009-05-23 09:13:15369 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
370 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52371
[email protected]ff007e162009-05-23 09:13:15372 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07373
374 void BypassHostCacheOnRefreshHelper(int load_flags);
375
376 void CheckErrorIsPassedBack(int error, IoMode mode);
377
[email protected]4bd46222013-05-14 19:32:23378 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07379 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03380
381 // Original socket limits. Some tests set these. Safest to always restore
382 // them once each test has been run.
383 int old_max_group_sockets_;
384 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15385};
[email protected]231d5a32008-09-13 00:45:27386
[email protected]23e482282013-06-14 16:08:02387INSTANTIATE_TEST_CASE_P(
388 NextProto,
389 HttpNetworkTransactionTest,
[email protected]b05bcaa32013-10-06 05:26:02390 testing::Values(kProtoDeprecatedSPDY2,
391 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
[email protected]88a332622013-07-30 07:13:32392 kProtoHTTP2Draft04));
[email protected]23e482282013-06-14 16:08:02393
[email protected]448d4ca52012-03-04 04:12:23394namespace {
395
[email protected]15a5ccf82008-10-23 19:57:43396// Fill |str| with a long header list that consumes >= |size| bytes.
397void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19398 const char* row =
399 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
400 const int sizeof_row = strlen(row);
401 const int num_rows = static_cast<int>(
402 ceil(static_cast<float>(size) / sizeof_row));
403 const int sizeof_data = num_rows * sizeof_row;
404 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43405 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51406
[email protected]4ddaf2502008-10-23 18:26:19407 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43408 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19409}
410
[email protected]385a4672009-03-11 22:21:29411// Alternative functions that eliminate randomness and dependency on the local
412// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20413void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29414 static const uint8 bytes[] = {
415 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
416 };
417 static size_t current_byte = 0;
418 for (size_t i = 0; i < n; ++i) {
419 output[i] = bytes[current_byte++];
420 current_byte %= arraysize(bytes);
421 }
422}
423
[email protected]fe2bc6a2009-03-23 16:52:20424void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29425 static const uint8 bytes[] = {
426 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
427 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
428 };
429 static size_t current_byte = 0;
430 for (size_t i = 0; i < n; ++i) {
431 output[i] = bytes[current_byte++];
432 current_byte %= arraysize(bytes);
433 }
434}
435
[email protected]fe2bc6a2009-03-23 16:52:20436std::string MockGetHostName() {
437 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29438}
439
[email protected]e60e47a2010-07-14 03:37:18440template<typename ParentPool>
441class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31442 public:
[email protected]9e1bdd32011-02-03 21:48:34443 CaptureGroupNameSocketPool(HostResolver* host_resolver,
444 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18445
[email protected]d80a4322009-08-14 07:07:49446 const std::string last_group_name_received() const {
447 return last_group_name_;
448 }
449
[email protected]684970b2009-08-14 04:54:46450 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49451 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31452 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31453 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41454 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53455 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31456 last_group_name_ = group_name;
457 return ERR_IO_PENDING;
458 }
[email protected]04e5be32009-06-26 20:00:31459 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21460 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31461 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44462 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19463 int id) {}
[email protected]04e5be32009-06-26 20:00:31464 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31465 virtual int IdleSocketCount() const {
466 return 0;
467 }
468 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
469 return 0;
470 }
471 virtual LoadState GetLoadState(const std::string& group_name,
472 const ClientSocketHandle* handle) const {
473 return LOAD_STATE_IDLE;
474 }
[email protected]a796bcec2010-03-22 17:17:26475 virtual base::TimeDelta ConnectionTimeout() const {
476 return base::TimeDelta();
477 }
[email protected]d80a4322009-08-14 07:07:49478
479 private:
[email protected]04e5be32009-06-26 20:00:31480 std::string last_group_name_;
481};
482
[email protected]ab739042011-04-07 15:22:28483typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
484CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13485typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
486CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06487typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11488CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18489typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
490CaptureGroupNameSSLSocketPool;
491
492template<typename ParentPool>
493CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34494 HostResolver* host_resolver,
495 CertVerifier* /* cert_verifier */)
496 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18497
498template<>
[email protected]2df19bb2010-08-25 20:13:46499CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34500 HostResolver* host_resolver,
501 CertVerifier* /* cert_verifier */)
502 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46503
[email protected]007b3f82013-04-09 08:46:45504template <>
[email protected]e60e47a2010-07-14 03:37:18505CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34506 HostResolver* host_resolver,
507 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45508 : SSLClientSocketPool(0,
509 0,
510 NULL,
511 host_resolver,
512 cert_verifier,
513 NULL,
514 NULL,
[email protected]284303b62013-11-28 15:11:54515 NULL,
[email protected]007b3f82013-04-09 08:46:45516 std::string(),
517 NULL,
518 NULL,
519 NULL,
520 NULL,
521 NULL,
522 NULL) {}
[email protected]2227c692010-05-04 15:36:11523
[email protected]231d5a32008-09-13 00:45:27524//-----------------------------------------------------------------------------
525
[email protected]79cb5c12011-09-12 13:12:04526// Helper functions for validating that AuthChallengeInfo's are correctly
527// configured for common cases.
528bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
529 if (!auth_challenge)
530 return false;
531 EXPECT_FALSE(auth_challenge->is_proxy);
532 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
533 EXPECT_EQ("MyRealm1", auth_challenge->realm);
534 EXPECT_EQ("basic", auth_challenge->scheme);
535 return true;
536}
537
538bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
539 if (!auth_challenge)
540 return false;
541 EXPECT_TRUE(auth_challenge->is_proxy);
542 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
543 EXPECT_EQ("MyRealm1", auth_challenge->realm);
544 EXPECT_EQ("basic", auth_challenge->scheme);
545 return true;
546}
547
548bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
549 if (!auth_challenge)
550 return false;
551 EXPECT_FALSE(auth_challenge->is_proxy);
552 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
553 EXPECT_EQ("digestive", auth_challenge->realm);
554 EXPECT_EQ("digest", auth_challenge->scheme);
555 return true;
556}
557
558bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
559 if (!auth_challenge)
560 return false;
561 EXPECT_FALSE(auth_challenge->is_proxy);
562 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
563 EXPECT_EQ(std::string(), auth_challenge->realm);
564 EXPECT_EQ("ntlm", auth_challenge->scheme);
565 return true;
566}
567
[email protected]448d4ca52012-03-04 04:12:23568} // namespace
569
[email protected]23e482282013-06-14 16:08:02570TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07571 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40572 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07573 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27574}
575
[email protected]23e482282013-06-14 16:08:02576TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27577 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35578 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
579 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06580 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27581 };
[email protected]31a2bfe2010-02-09 08:03:39582 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
583 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42584 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27585 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
586 EXPECT_EQ("hello world", out.response_data);
587}
588
589// Response with no status line.
[email protected]23e482282013-06-14 16:08:02590TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27591 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35592 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06593 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27594 };
[email protected]31a2bfe2010-02-09 08:03:39595 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
596 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42597 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27598 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
599 EXPECT_EQ("hello world", out.response_data);
600}
601
602// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02603TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27604 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35605 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06606 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27607 };
[email protected]31a2bfe2010-02-09 08:03:39608 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
609 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42610 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27611 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
612 EXPECT_EQ("DATA", out.response_data);
613}
614
615// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02616TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27617 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35618 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06619 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27620 };
[email protected]31a2bfe2010-02-09 08:03:39621 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
622 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42623 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27624 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
625 EXPECT_EQ("DATA", out.response_data);
626}
627
628// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02629TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27630 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35631 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06632 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27633 };
[email protected]31a2bfe2010-02-09 08:03:39634 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
635 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42636 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25637 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
638 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27639}
640
641// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02642TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27643 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35644 MockRead("\n"),
645 MockRead("\n"),
646 MockRead("Q"),
647 MockRead("J"),
648 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06649 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27650 };
[email protected]31a2bfe2010-02-09 08:03:39651 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
652 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42653 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27654 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
655 EXPECT_EQ("DATA", out.response_data);
656}
657
658// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02659TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27660 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35661 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06662 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27663 };
[email protected]31a2bfe2010-02-09 08:03:39664 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
665 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42666 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27667 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
668 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52669}
670
[email protected]f9d44aa2008-09-23 23:57:17671// Simulate a 204 response, lacking a Content-Length header, sent over a
672// persistent connection. The response should still terminate since a 204
673// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02674TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]f9d44aa2008-09-23 23:57:17675 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35676 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
677 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06678 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17679 };
[email protected]31a2bfe2010-02-09 08:03:39680 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
681 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42682 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17683 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
684 EXPECT_EQ("", out.response_data);
685}
686
[email protected]0877e3d2009-10-17 22:29:57687// A simple request using chunked encoding with some extra data after.
688// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02689TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]0877e3d2009-10-17 22:29:57690 MockRead data_reads[] = {
691 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
692 MockRead("5\r\nHello\r\n"),
693 MockRead("1\r\n"),
694 MockRead(" \r\n"),
695 MockRead("5\r\nworld\r\n"),
696 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06697 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57698 };
[email protected]31a2bfe2010-02-09 08:03:39699 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
700 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57701 EXPECT_EQ(OK, out.rv);
702 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
703 EXPECT_EQ("Hello world", out.response_data);
704}
705
[email protected]9fe44f52010-09-23 18:36:00706// Next tests deal with http://crbug.com/56344.
707
[email protected]23e482282013-06-14 16:08:02708TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00709 MultipleContentLengthHeadersNoTransferEncoding) {
710 MockRead data_reads[] = {
711 MockRead("HTTP/1.1 200 OK\r\n"),
712 MockRead("Content-Length: 10\r\n"),
713 MockRead("Content-Length: 5\r\n\r\n"),
714 };
715 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
716 arraysize(data_reads));
717 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
718}
719
[email protected]23e482282013-06-14 16:08:02720TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04721 DuplicateContentLengthHeadersNoTransferEncoding) {
722 MockRead data_reads[] = {
723 MockRead("HTTP/1.1 200 OK\r\n"),
724 MockRead("Content-Length: 5\r\n"),
725 MockRead("Content-Length: 5\r\n\r\n"),
726 MockRead("Hello"),
727 };
728 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
729 arraysize(data_reads));
730 EXPECT_EQ(OK, out.rv);
731 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
732 EXPECT_EQ("Hello", out.response_data);
733}
734
[email protected]23e482282013-06-14 16:08:02735TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04736 ComplexContentLengthHeadersNoTransferEncoding) {
737 // More than 2 dupes.
738 {
739 MockRead data_reads[] = {
740 MockRead("HTTP/1.1 200 OK\r\n"),
741 MockRead("Content-Length: 5\r\n"),
742 MockRead("Content-Length: 5\r\n"),
743 MockRead("Content-Length: 5\r\n\r\n"),
744 MockRead("Hello"),
745 };
746 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
747 arraysize(data_reads));
748 EXPECT_EQ(OK, out.rv);
749 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
750 EXPECT_EQ("Hello", out.response_data);
751 }
752 // HTTP/1.0
753 {
754 MockRead data_reads[] = {
755 MockRead("HTTP/1.0 200 OK\r\n"),
756 MockRead("Content-Length: 5\r\n"),
757 MockRead("Content-Length: 5\r\n"),
758 MockRead("Content-Length: 5\r\n\r\n"),
759 MockRead("Hello"),
760 };
761 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
762 arraysize(data_reads));
763 EXPECT_EQ(OK, out.rv);
764 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
765 EXPECT_EQ("Hello", out.response_data);
766 }
767 // 2 dupes and one mismatched.
768 {
769 MockRead data_reads[] = {
770 MockRead("HTTP/1.1 200 OK\r\n"),
771 MockRead("Content-Length: 10\r\n"),
772 MockRead("Content-Length: 10\r\n"),
773 MockRead("Content-Length: 5\r\n\r\n"),
774 };
775 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
776 arraysize(data_reads));
777 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
778 }
779}
780
[email protected]23e482282013-06-14 16:08:02781TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00782 MultipleContentLengthHeadersTransferEncoding) {
783 MockRead data_reads[] = {
784 MockRead("HTTP/1.1 200 OK\r\n"),
785 MockRead("Content-Length: 666\r\n"),
786 MockRead("Content-Length: 1337\r\n"),
787 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
788 MockRead("5\r\nHello\r\n"),
789 MockRead("1\r\n"),
790 MockRead(" \r\n"),
791 MockRead("5\r\nworld\r\n"),
792 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06793 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00794 };
795 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
796 arraysize(data_reads));
797 EXPECT_EQ(OK, out.rv);
798 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
799 EXPECT_EQ("Hello world", out.response_data);
800}
801
[email protected]1628fe92011-10-04 23:04:55802// Next tests deal with http://crbug.com/98895.
803
804// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02805TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55806 MockRead data_reads[] = {
807 MockRead("HTTP/1.1 200 OK\r\n"),
808 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"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
[email protected]54a9c6e52012-03-21 20:10:59819// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02820TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59821 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55822 MockRead data_reads[] = {
823 MockRead("HTTP/1.1 200 OK\r\n"),
824 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
825 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
826 MockRead("Content-Length: 5\r\n\r\n"),
827 MockRead("Hello"),
828 };
829 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
830 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59831 EXPECT_EQ(OK, out.rv);
832 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
833 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55834}
835
836// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02837TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55838 MockRead data_reads[] = {
839 MockRead("HTTP/1.1 200 OK\r\n"),
840 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
841 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
842 MockRead("Content-Length: 5\r\n\r\n"),
843 MockRead("Hello"),
844 };
845 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
846 arraysize(data_reads));
847 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
848}
849
[email protected]54a9c6e52012-03-21 20:10:59850// Checks that two identical Location headers result in no error.
851// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02852TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55853 MockRead data_reads[] = {
854 MockRead("HTTP/1.1 302 Redirect\r\n"),
855 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59856 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55857 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06858 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55859 };
860
861 HttpRequestInfo request;
862 request.method = "GET";
863 request.url = GURL("http://redirect.com/");
864 request.load_flags = 0;
865
[email protected]3fe8d2f82013-10-17 08:56:07866 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55867 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55869
870 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55872
[email protected]49639fa2011-12-20 23:22:41873 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55874
[email protected]49639fa2011-12-20 23:22:41875 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55876 EXPECT_EQ(ERR_IO_PENDING, rv);
877
878 EXPECT_EQ(OK, callback.WaitForResult());
879
880 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50881 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55882 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
883 std::string url;
884 EXPECT_TRUE(response->headers->IsRedirect(&url));
885 EXPECT_EQ("http://good.com/", url);
886}
887
[email protected]1628fe92011-10-04 23:04:55888// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02889TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55890 MockRead data_reads[] = {
891 MockRead("HTTP/1.1 302 Redirect\r\n"),
892 MockRead("Location: http://good.com/\r\n"),
893 MockRead("Location: http://evil.com/\r\n"),
894 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06895 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55896 };
897 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
898 arraysize(data_reads));
899 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
900}
901
[email protected]ef0faf2e72009-03-05 23:27:23902// Do a request using the HEAD method. Verify that we don't try to read the
903// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02904TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42905 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23906 request.method = "HEAD";
907 request.url = GURL("http://www.google.com/");
908 request.load_flags = 0;
909
[email protected]3fe8d2f82013-10-17 08:56:07910 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27911 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07912 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27913
[email protected]ef0faf2e72009-03-05 23:27:23914 MockWrite data_writes1[] = {
915 MockWrite("HEAD / HTTP/1.1\r\n"
916 "Host: www.google.com\r\n"
917 "Connection: keep-alive\r\n"
918 "Content-Length: 0\r\n\r\n"),
919 };
920 MockRead data_reads1[] = {
921 MockRead("HTTP/1.1 404 Not Found\r\n"),
922 MockRead("Server: Blah\r\n"),
923 MockRead("Content-Length: 1234\r\n\r\n"),
924
925 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06926 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23927 };
928
[email protected]31a2bfe2010-02-09 08:03:39929 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
930 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23932
[email protected]49639fa2011-12-20 23:22:41933 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23934
[email protected]49639fa2011-12-20 23:22:41935 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42936 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23937
938 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42939 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23940
[email protected]1c773ea12009-04-28 19:58:42941 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50942 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23943
944 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:50945 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23946 EXPECT_EQ(1234, response->headers->GetContentLength());
947 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
948
949 std::string server_header;
950 void* iter = NULL;
951 bool has_server_header = response->headers->EnumerateHeader(
952 &iter, "Server", &server_header);
953 EXPECT_TRUE(has_server_header);
954 EXPECT_EQ("Blah", server_header);
955
956 // Reading should give EOF right away, since there is no message body
957 // (despite non-zero content-length).
958 std::string response_data;
959 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42960 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23961 EXPECT_EQ("", response_data);
962}
963
[email protected]23e482282013-06-14 16:08:02964TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:07965 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:52966
967 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35968 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
969 MockRead("hello"),
970 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
971 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:06972 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:52973 };
[email protected]31a2bfe2010-02-09 08:03:39974 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07975 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52976
[email protected]0b0bf032010-09-21 18:08:50977 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:52978 "hello", "world"
979 };
980
981 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42982 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52983 request.method = "GET";
984 request.url = GURL("http://www.google.com/");
985 request.load_flags = 0;
986
[email protected]262eec82013-03-19 21:01:36987 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:50988 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27989
[email protected]49639fa2011-12-20 23:22:41990 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52991
[email protected]49639fa2011-12-20 23:22:41992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42993 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52994
995 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42996 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52997
[email protected]1c773ea12009-04-28 19:58:42998 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50999 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521000
[email protected]90499482013-06-01 00:39:501001 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251002 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521003
1004 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571005 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421006 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251007 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521008 }
1009}
1010
[email protected]23e482282013-06-14 16:08:021011TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061012 ScopedVector<UploadElementReader> element_readers;
1013 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201014 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271015
[email protected]1c773ea12009-04-28 19:58:421016 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521017 request.method = "POST";
1018 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271019 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521020 request.load_flags = 0;
1021
[email protected]3fe8d2f82013-10-17 08:56:071022 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271023 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071024 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271025
initial.commit586acc5fe2008-07-26 22:42:521026 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351027 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1028 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1029 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061030 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521031 };
[email protected]31a2bfe2010-02-09 08:03:391032 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071033 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521034
[email protected]49639fa2011-12-20 23:22:411035 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521036
[email protected]49639fa2011-12-20 23:22:411037 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421038 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521039
1040 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421041 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521042
[email protected]1c773ea12009-04-28 19:58:421043 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501044 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521045
[email protected]90499482013-06-01 00:39:501046 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251047 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521048
1049 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571050 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421051 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251052 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521053}
1054
[email protected]3a2d3662009-03-27 03:49:141055// This test is almost the same as Ignores100 above, but the response contains
1056// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571057// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021058TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421059 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141060 request.method = "GET";
1061 request.url = GURL("http://www.foo.com/");
1062 request.load_flags = 0;
1063
[email protected]3fe8d2f82013-10-17 08:56:071064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271065 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271067
[email protected]3a2d3662009-03-27 03:49:141068 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571069 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1070 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141071 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061072 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141073 };
[email protected]31a2bfe2010-02-09 08:03:391074 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071075 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141076
[email protected]49639fa2011-12-20 23:22:411077 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141078
[email protected]49639fa2011-12-20 23:22:411079 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421080 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141081
1082 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421083 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141084
[email protected]1c773ea12009-04-28 19:58:421085 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501086 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141087
[email protected]90499482013-06-01 00:39:501088 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141089 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1090
1091 std::string response_data;
1092 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421093 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141094 EXPECT_EQ("hello world", response_data);
1095}
1096
[email protected]23e482282013-06-14 16:08:021097TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381098 HttpRequestInfo request;
1099 request.method = "POST";
1100 request.url = GURL("http://www.foo.com/");
1101 request.load_flags = 0;
1102
[email protected]3fe8d2f82013-10-17 08:56:071103 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271104 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071105 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271106
[email protected]ee9410e72010-01-07 01:42:381107 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061108 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1109 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381110 };
[email protected]31a2bfe2010-02-09 08:03:391111 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071112 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381113
[email protected]49639fa2011-12-20 23:22:411114 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381115
[email protected]49639fa2011-12-20 23:22:411116 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381117 EXPECT_EQ(ERR_IO_PENDING, rv);
1118
1119 rv = callback.WaitForResult();
1120 EXPECT_EQ(OK, rv);
1121
1122 std::string response_data;
1123 rv = ReadTransaction(trans.get(), &response_data);
1124 EXPECT_EQ(OK, rv);
1125 EXPECT_EQ("", response_data);
1126}
1127
[email protected]23e482282013-06-14 16:08:021128TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381129 HttpRequestInfo request;
1130 request.method = "POST";
1131 request.url = GURL("http://www.foo.com/");
1132 request.load_flags = 0;
1133
[email protected]3fe8d2f82013-10-17 08:56:071134 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271135 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1137
[email protected]cb9bf6ca2011-01-28 13:15:271138
[email protected]ee9410e72010-01-07 01:42:381139 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061140 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381141 };
[email protected]31a2bfe2010-02-09 08:03:391142 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071143 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381144
[email protected]49639fa2011-12-20 23:22:411145 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381146
[email protected]49639fa2011-12-20 23:22:411147 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381148 EXPECT_EQ(ERR_IO_PENDING, rv);
1149
1150 rv = callback.WaitForResult();
1151 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1152}
1153
[email protected]23e482282013-06-14 16:08:021154void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511155 const MockWrite* write_failure,
1156 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421157 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521158 request.method = "GET";
1159 request.url = GURL("http://www.foo.com/");
1160 request.load_flags = 0;
1161
[email protected]58e32bb2013-01-21 18:23:251162 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071163 session_deps_.net_log = &net_log;
1164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271165
[email protected]202965992011-12-07 23:04:511166 // Written data for successfully sending both requests.
1167 MockWrite data1_writes[] = {
1168 MockWrite("GET / HTTP/1.1\r\n"
1169 "Host: www.foo.com\r\n"
1170 "Connection: keep-alive\r\n\r\n"),
1171 MockWrite("GET / HTTP/1.1\r\n"
1172 "Host: www.foo.com\r\n"
1173 "Connection: keep-alive\r\n\r\n")
1174 };
1175
1176 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521177 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351178 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1179 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061180 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521181 };
[email protected]202965992011-12-07 23:04:511182
1183 if (write_failure) {
1184 ASSERT_TRUE(!read_failure);
1185 data1_writes[1] = *write_failure;
1186 } else {
1187 ASSERT_TRUE(read_failure);
1188 data1_reads[2] = *read_failure;
1189 }
1190
1191 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1192 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071193 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521194
1195 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351196 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1197 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061198 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521199 };
[email protected]31a2bfe2010-02-09 08:03:391200 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071201 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521202
1203 const char* kExpectedResponseData[] = {
1204 "hello", "world"
1205 };
1206
[email protected]58e32bb2013-01-21 18:23:251207 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521208 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411209 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521210
[email protected]262eec82013-03-19 21:01:361211 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521213
[email protected]49639fa2011-12-20 23:22:411214 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421215 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521216
1217 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421218 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521219
[email protected]58e32bb2013-01-21 18:23:251220 LoadTimingInfo load_timing_info;
1221 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1222 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1223 if (i == 0) {
1224 first_socket_log_id = load_timing_info.socket_log_id;
1225 } else {
1226 // The second request should be using a new socket.
1227 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1228 }
1229
[email protected]1c773ea12009-04-28 19:58:421230 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501231 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521232
[email protected]90499482013-06-01 00:39:501233 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251234 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521235
1236 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571237 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421238 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251239 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521240 }
1241}
[email protected]3d2a59b2008-09-26 19:44:251242
[email protected]23e482282013-06-14 16:08:021243TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231244 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061245 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511246 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1247}
1248
[email protected]23e482282013-06-14 16:08:021249TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061250 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511251 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251252}
1253
[email protected]23e482282013-06-14 16:08:021254TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061255 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511256 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251257}
1258
[email protected]23e482282013-06-14 16:08:021259TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421260 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251261 request.method = "GET";
1262 request.url = GURL("http://www.google.com/");
1263 request.load_flags = 0;
1264
[email protected]3fe8d2f82013-10-17 08:56:071265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271266 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271268
[email protected]3d2a59b2008-09-26 19:44:251269 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061270 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351271 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1272 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061273 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251274 };
[email protected]31a2bfe2010-02-09 08:03:391275 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071276 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251277
[email protected]49639fa2011-12-20 23:22:411278 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251279
[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);
[email protected]3d2a59b2008-09-26 19:44:251282
1283 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421284 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251285
[email protected]1c773ea12009-04-28 19:58:421286 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251287 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251288}
1289
1290// What do various browsers do when the server closes a non-keepalive
1291// connection without sending any response header or body?
1292//
1293// IE7: error page
1294// Safari 3.1.2 (Windows): error page
1295// Firefox 3.0.1: blank page
1296// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421297// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1298// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021299TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251300 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061301 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351302 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1303 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061304 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251305 };
[email protected]31a2bfe2010-02-09 08:03:391306 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1307 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421308 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251309}
[email protected]038e9a32008-10-08 22:40:161310
[email protected]7a5378b2012-11-04 03:25:171311// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1312// tests. There was a bug causing HttpNetworkTransaction to hang in the
1313// destructor in such situations.
1314// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021315TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171316 HttpRequestInfo request;
1317 request.method = "GET";
1318 request.url = GURL("http://www.google.com/");
1319 request.load_flags = 0;
1320
[email protected]bb88e1d32013-05-03 23:11:071321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361322 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171324
1325 MockRead data_reads[] = {
1326 MockRead("HTTP/1.0 200 OK\r\n"),
1327 MockRead("Connection: keep-alive\r\n"),
1328 MockRead("Content-Length: 100\r\n\r\n"),
1329 MockRead("hello"),
1330 MockRead(SYNCHRONOUS, 0),
1331 };
1332 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071333 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171334
1335 TestCompletionCallback callback;
1336
1337 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1338 EXPECT_EQ(ERR_IO_PENDING, rv);
1339
1340 rv = callback.WaitForResult();
1341 EXPECT_EQ(OK, rv);
1342
1343 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501344 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171345 if (rv == ERR_IO_PENDING)
1346 rv = callback.WaitForResult();
1347 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501348 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171349 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1350
1351 trans.reset();
[email protected]2da659e2013-05-23 20:51:341352 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171353 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1354}
1355
[email protected]23e482282013-06-14 16:08:021356TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171357 HttpRequestInfo request;
1358 request.method = "GET";
1359 request.url = GURL("http://www.google.com/");
1360 request.load_flags = 0;
1361
[email protected]bb88e1d32013-05-03 23:11:071362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361363 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171365
1366 MockRead data_reads[] = {
1367 MockRead("HTTP/1.0 200 OK\r\n"),
1368 MockRead("Connection: keep-alive\r\n"),
1369 MockRead("Content-Length: 100\r\n\r\n"),
1370 MockRead(SYNCHRONOUS, 0),
1371 };
1372 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071373 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171374
1375 TestCompletionCallback callback;
1376
1377 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1378 EXPECT_EQ(ERR_IO_PENDING, rv);
1379
1380 rv = callback.WaitForResult();
1381 EXPECT_EQ(OK, rv);
1382
1383 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501384 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171385 if (rv == ERR_IO_PENDING)
1386 rv = callback.WaitForResult();
1387 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1388
1389 trans.reset();
[email protected]2da659e2013-05-23 20:51:341390 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171391 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1392}
1393
[email protected]0b0bf032010-09-21 18:08:501394// Test that we correctly reuse a keep-alive connection after not explicitly
1395// reading the body.
[email protected]23e482282013-06-14 16:08:021396TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131397 HttpRequestInfo request;
1398 request.method = "GET";
1399 request.url = GURL("http://www.foo.com/");
1400 request.load_flags = 0;
1401
[email protected]58e32bb2013-01-21 18:23:251402 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071403 session_deps_.net_log = &net_log;
1404 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271405
[email protected]0b0bf032010-09-21 18:08:501406 // Note that because all these reads happen in the same
1407 // StaticSocketDataProvider, it shows that the same socket is being reused for
1408 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131409 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501410 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1411 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131412 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501413 MockRead("HTTP/1.1 302 Found\r\n"
1414 "Content-Length: 0\r\n\r\n"),
1415 MockRead("HTTP/1.1 302 Found\r\n"
1416 "Content-Length: 5\r\n\r\n"
1417 "hello"),
1418 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1419 "Content-Length: 0\r\n\r\n"),
1420 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1421 "Content-Length: 5\r\n\r\n"
1422 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131423 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1424 MockRead("hello"),
1425 };
1426 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131428
1429 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061430 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131431 };
1432 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071433 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131434
[email protected]0b0bf032010-09-21 18:08:501435 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1436 std::string response_lines[kNumUnreadBodies];
1437
[email protected]58e32bb2013-01-21 18:23:251438 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501439 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411440 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131441
[email protected]262eec82013-03-19 21:01:361442 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501443 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131444
[email protected]49639fa2011-12-20 23:22:411445 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131446 EXPECT_EQ(ERR_IO_PENDING, rv);
1447
1448 rv = callback.WaitForResult();
1449 EXPECT_EQ(OK, rv);
1450
[email protected]58e32bb2013-01-21 18:23:251451 LoadTimingInfo load_timing_info;
1452 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1453 if (i == 0) {
1454 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1455 first_socket_log_id = load_timing_info.socket_log_id;
1456 } else {
1457 TestLoadTimingReused(load_timing_info);
1458 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1459 }
1460
[email protected]fc31d6a42010-06-24 18:05:131461 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501462 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131463
[email protected]90499482013-06-01 00:39:501464 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501465 response_lines[i] = response->headers->GetStatusLine();
1466
1467 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131468 }
[email protected]0b0bf032010-09-21 18:08:501469
1470 const char* const kStatusLines[] = {
1471 "HTTP/1.1 204 No Content",
1472 "HTTP/1.1 205 Reset Content",
1473 "HTTP/1.1 304 Not Modified",
1474 "HTTP/1.1 302 Found",
1475 "HTTP/1.1 302 Found",
1476 "HTTP/1.1 301 Moved Permanently",
1477 "HTTP/1.1 301 Moved Permanently",
1478 };
1479
1480 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1481 forgot_to_update_kStatusLines);
1482
1483 for (int i = 0; i < kNumUnreadBodies; ++i)
1484 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1485
[email protected]49639fa2011-12-20 23:22:411486 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361487 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501488 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411489 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501490 EXPECT_EQ(ERR_IO_PENDING, rv);
1491 rv = callback.WaitForResult();
1492 EXPECT_EQ(OK, rv);
1493 const HttpResponseInfo* response = trans->GetResponseInfo();
1494 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501495 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501496 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1497 std::string response_data;
1498 rv = ReadTransaction(trans.get(), &response_data);
1499 EXPECT_EQ(OK, rv);
1500 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131501}
1502
[email protected]038e9a32008-10-08 22:40:161503// Test the request-challenge-retry sequence for basic auth.
1504// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021505TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421506 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161507 request.method = "GET";
1508 request.url = GURL("http://www.google.com/");
1509 request.load_flags = 0;
1510
[email protected]58e32bb2013-01-21 18:23:251511 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071512 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071513 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271514 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071515 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271516
[email protected]f9ee6b52008-11-08 06:46:231517 MockWrite data_writes1[] = {
1518 MockWrite("GET / HTTP/1.1\r\n"
1519 "Host: www.google.com\r\n"
1520 "Connection: keep-alive\r\n\r\n"),
1521 };
1522
[email protected]038e9a32008-10-08 22:40:161523 MockRead data_reads1[] = {
1524 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1525 // Give a couple authenticate options (only the middle one is actually
1526 // supported).
[email protected]22927ad2009-09-21 19:56:191527 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161528 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1529 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1530 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1531 // Large content-length -- won't matter, as connection will be reset.
1532 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061533 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161534 };
1535
1536 // After calling trans->RestartWithAuth(), this is the request we should
1537 // be issuing -- the final header line contains the credentials.
1538 MockWrite data_writes2[] = {
1539 MockWrite("GET / HTTP/1.1\r\n"
1540 "Host: www.google.com\r\n"
1541 "Connection: keep-alive\r\n"
1542 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1543 };
1544
1545 // Lastly, the server responds with the actual content.
1546 MockRead data_reads2[] = {
1547 MockRead("HTTP/1.0 200 OK\r\n"),
1548 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1549 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061550 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161551 };
1552
[email protected]31a2bfe2010-02-09 08:03:391553 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1554 data_writes1, arraysize(data_writes1));
1555 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1556 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071557 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1558 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161559
[email protected]49639fa2011-12-20 23:22:411560 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161561
[email protected]49639fa2011-12-20 23:22:411562 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421563 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161564
1565 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421566 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161567
[email protected]58e32bb2013-01-21 18:23:251568 LoadTimingInfo load_timing_info1;
1569 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1570 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1571
[email protected]1c773ea12009-04-28 19:58:421572 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501573 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041574 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161575
[email protected]49639fa2011-12-20 23:22:411576 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161577
[email protected]49639fa2011-12-20 23:22:411578 rv = trans->RestartWithAuth(
1579 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421580 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161581
1582 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421583 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161584
[email protected]58e32bb2013-01-21 18:23:251585 LoadTimingInfo load_timing_info2;
1586 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1587 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1588 // The load timing after restart should have a new socket ID, and times after
1589 // those of the first load timing.
1590 EXPECT_LE(load_timing_info1.receive_headers_end,
1591 load_timing_info2.connect_timing.connect_start);
1592 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1593
[email protected]038e9a32008-10-08 22:40:161594 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501595 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161596 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1597 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161598}
1599
[email protected]23e482282013-06-14 16:08:021600TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461601 HttpRequestInfo request;
1602 request.method = "GET";
1603 request.url = GURL("http://www.google.com/");
1604 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1605
[email protected]3fe8d2f82013-10-17 08:56:071606 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271607 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271609
[email protected]861fcd52009-08-26 02:33:461610 MockWrite data_writes[] = {
1611 MockWrite("GET / HTTP/1.1\r\n"
1612 "Host: www.google.com\r\n"
1613 "Connection: keep-alive\r\n\r\n"),
1614 };
1615
1616 MockRead data_reads[] = {
1617 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1618 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1619 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1620 // Large content-length -- won't matter, as connection will be reset.
1621 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061622 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461623 };
1624
[email protected]31a2bfe2010-02-09 08:03:391625 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1626 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071627 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411628 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461629
[email protected]49639fa2011-12-20 23:22:411630 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461631 EXPECT_EQ(ERR_IO_PENDING, rv);
1632
1633 rv = callback.WaitForResult();
1634 EXPECT_EQ(0, rv);
1635
1636 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501637 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461638 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1639}
1640
[email protected]2d2697f92009-02-18 21:00:321641// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1642// connection.
[email protected]23e482282013-06-14 16:08:021643TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421644 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321645 request.method = "GET";
1646 request.url = GURL("http://www.google.com/");
1647 request.load_flags = 0;
1648
[email protected]58e32bb2013-01-21 18:23:251649 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071650 session_deps_.net_log = &log;
1651 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271652
[email protected]2d2697f92009-02-18 21:00:321653 MockWrite data_writes1[] = {
1654 MockWrite("GET / HTTP/1.1\r\n"
1655 "Host: www.google.com\r\n"
1656 "Connection: keep-alive\r\n\r\n"),
1657
1658 // After calling trans->RestartWithAuth(), this is the request we should
1659 // be issuing -- the final header line contains the credentials.
1660 MockWrite("GET / HTTP/1.1\r\n"
1661 "Host: www.google.com\r\n"
1662 "Connection: keep-alive\r\n"
1663 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1664 };
1665
1666 MockRead data_reads1[] = {
1667 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1668 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1669 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1670 MockRead("Content-Length: 14\r\n\r\n"),
1671 MockRead("Unauthorized\r\n"),
1672
1673 // Lastly, the server responds with the actual content.
1674 MockRead("HTTP/1.1 200 OK\r\n"),
1675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501676 MockRead("Content-Length: 5\r\n\r\n"),
1677 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321678 };
1679
[email protected]2d0a4f92011-05-05 16:38:461680 // If there is a regression where we disconnect a Keep-Alive
1681 // connection during an auth roundtrip, we'll end up reading this.
1682 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061683 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461684 };
1685
[email protected]31a2bfe2010-02-09 08:03:391686 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1687 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461688 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1689 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071690 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1691 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321692
[email protected]49639fa2011-12-20 23:22:411693 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321694
[email protected]262eec82013-03-19 21:01:361695 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501696 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411697 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421698 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321699
1700 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421701 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321702
[email protected]58e32bb2013-01-21 18:23:251703 LoadTimingInfo load_timing_info1;
1704 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1705 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1706
[email protected]1c773ea12009-04-28 19:58:421707 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501708 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041709 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321710
[email protected]49639fa2011-12-20 23:22:411711 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321712
[email protected]49639fa2011-12-20 23:22:411713 rv = trans->RestartWithAuth(
1714 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421715 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321716
1717 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421718 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321719
[email protected]58e32bb2013-01-21 18:23:251720 LoadTimingInfo load_timing_info2;
1721 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1722 TestLoadTimingReused(load_timing_info2);
1723 // The load timing after restart should have the same socket ID, and times
1724 // those of the first load timing.
1725 EXPECT_LE(load_timing_info1.receive_headers_end,
1726 load_timing_info2.send_start);
1727 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1728
[email protected]2d2697f92009-02-18 21:00:321729 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501730 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321731 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501732 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321733}
1734
1735// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1736// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021737TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421738 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321739 request.method = "GET";
1740 request.url = GURL("http://www.google.com/");
1741 request.load_flags = 0;
1742
[email protected]bb88e1d32013-05-03 23:11:071743 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271744
[email protected]2d2697f92009-02-18 21:00:321745 MockWrite data_writes1[] = {
1746 MockWrite("GET / HTTP/1.1\r\n"
1747 "Host: www.google.com\r\n"
1748 "Connection: keep-alive\r\n\r\n"),
1749
1750 // After calling trans->RestartWithAuth(), this is the request we should
1751 // be issuing -- the final header line contains the credentials.
1752 MockWrite("GET / HTTP/1.1\r\n"
1753 "Host: www.google.com\r\n"
1754 "Connection: keep-alive\r\n"
1755 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1756 };
1757
[email protected]2d2697f92009-02-18 21:00:321758 MockRead data_reads1[] = {
1759 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1760 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311761 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321762
1763 // Lastly, the server responds with the actual content.
1764 MockRead("HTTP/1.1 200 OK\r\n"),
1765 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501766 MockRead("Content-Length: 5\r\n\r\n"),
1767 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321768 };
1769
[email protected]2d0a4f92011-05-05 16:38:461770 // An incorrect reconnect would cause this to be read.
1771 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061772 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461773 };
1774
[email protected]31a2bfe2010-02-09 08:03:391775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1776 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461777 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1778 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071779 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1780 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321781
[email protected]49639fa2011-12-20 23:22:411782 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321783
[email protected]262eec82013-03-19 21:01:361784 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411786 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421787 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321788
1789 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421790 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321791
[email protected]1c773ea12009-04-28 19:58:421792 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501793 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041794 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321795
[email protected]49639fa2011-12-20 23:22:411796 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321797
[email protected]49639fa2011-12-20 23:22:411798 rv = trans->RestartWithAuth(
1799 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421800 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321801
1802 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421803 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321804
1805 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501806 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321807 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501808 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321809}
1810
1811// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1812// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:021813TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421814 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321815 request.method = "GET";
1816 request.url = GURL("http://www.google.com/");
1817 request.load_flags = 0;
1818
[email protected]bb88e1d32013-05-03 23:11:071819 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271820
[email protected]2d2697f92009-02-18 21:00:321821 MockWrite data_writes1[] = {
1822 MockWrite("GET / HTTP/1.1\r\n"
1823 "Host: www.google.com\r\n"
1824 "Connection: keep-alive\r\n\r\n"),
1825
1826 // After calling trans->RestartWithAuth(), this is the request we should
1827 // be issuing -- the final header line contains the credentials.
1828 MockWrite("GET / HTTP/1.1\r\n"
1829 "Host: www.google.com\r\n"
1830 "Connection: keep-alive\r\n"
1831 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1832 };
1833
1834 // Respond with 5 kb of response body.
1835 std::string large_body_string("Unauthorized");
1836 large_body_string.append(5 * 1024, ' ');
1837 large_body_string.append("\r\n");
1838
1839 MockRead data_reads1[] = {
1840 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1841 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1842 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1843 // 5134 = 12 + 5 * 1024 + 2
1844 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061845 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:321846
1847 // Lastly, the server responds with the actual content.
1848 MockRead("HTTP/1.1 200 OK\r\n"),
1849 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501850 MockRead("Content-Length: 5\r\n\r\n"),
1851 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321852 };
1853
[email protected]2d0a4f92011-05-05 16:38:461854 // An incorrect reconnect would cause this to be read.
1855 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061856 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461857 };
1858
[email protected]31a2bfe2010-02-09 08:03:391859 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1860 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461861 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1862 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071863 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1864 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321865
[email protected]49639fa2011-12-20 23:22:411866 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321867
[email protected]262eec82013-03-19 21:01:361868 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501869 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411870 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421871 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321872
1873 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421874 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321875
[email protected]1c773ea12009-04-28 19:58:421876 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501877 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041878 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321879
[email protected]49639fa2011-12-20 23:22:411880 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321881
[email protected]49639fa2011-12-20 23:22:411882 rv = trans->RestartWithAuth(
1883 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421884 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321885
1886 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421887 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321888
1889 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501890 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321891 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501892 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321893}
1894
1895// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:311896// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:021897TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:311898 HttpRequestInfo request;
1899 request.method = "GET";
1900 request.url = GURL("http://www.google.com/");
1901 request.load_flags = 0;
1902
[email protected]bb88e1d32013-05-03 23:11:071903 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271904
[email protected]11203f012009-11-12 23:02:311905 MockWrite data_writes1[] = {
1906 MockWrite("GET / HTTP/1.1\r\n"
1907 "Host: www.google.com\r\n"
1908 "Connection: keep-alive\r\n\r\n"),
1909 // This simulates the seemingly successful write to a closed connection
1910 // if the bug is not fixed.
1911 MockWrite("GET / HTTP/1.1\r\n"
1912 "Host: www.google.com\r\n"
1913 "Connection: keep-alive\r\n"
1914 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1915 };
1916
1917 MockRead data_reads1[] = {
1918 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1919 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1920 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1921 MockRead("Content-Length: 14\r\n\r\n"),
1922 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:061923 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:311924 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:061925 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:311926 };
1927
1928 // After calling trans->RestartWithAuth(), this is the request we should
1929 // be issuing -- the final header line contains the credentials.
1930 MockWrite data_writes2[] = {
1931 MockWrite("GET / HTTP/1.1\r\n"
1932 "Host: www.google.com\r\n"
1933 "Connection: keep-alive\r\n"
1934 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1935 };
1936
1937 // Lastly, the server responds with the actual content.
1938 MockRead data_reads2[] = {
1939 MockRead("HTTP/1.1 200 OK\r\n"),
1940 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501941 MockRead("Content-Length: 5\r\n\r\n"),
1942 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:311943 };
1944
[email protected]31a2bfe2010-02-09 08:03:391945 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1946 data_writes1, arraysize(data_writes1));
1947 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1948 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071949 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1950 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:311951
[email protected]49639fa2011-12-20 23:22:411952 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:311953
[email protected]262eec82013-03-19 21:01:361954 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501955 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411956 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:311957 EXPECT_EQ(ERR_IO_PENDING, rv);
1958
1959 rv = callback1.WaitForResult();
1960 EXPECT_EQ(OK, rv);
1961
1962 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501963 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041964 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:311965
[email protected]49639fa2011-12-20 23:22:411966 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:311967
[email protected]49639fa2011-12-20 23:22:411968 rv = trans->RestartWithAuth(
1969 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:311970 EXPECT_EQ(ERR_IO_PENDING, rv);
1971
1972 rv = callback2.WaitForResult();
1973 EXPECT_EQ(OK, rv);
1974
1975 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501976 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:311977 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501978 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:311979}
1980
[email protected]394816e92010-08-03 07:38:591981// Test the request-challenge-retry sequence for basic auth, over a connection
1982// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:021983TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:591984 HttpRequestInfo request;
1985 request.method = "GET";
1986 request.url = GURL("https://www.google.com/");
1987 // when the no authentication data flag is set.
1988 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1989
[email protected]cb9bf6ca2011-01-28 13:15:271990 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:071991 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:201992 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:291993 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071994 session_deps_.net_log = log.bound().net_log();
1995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271996
[email protected]394816e92010-08-03 07:38:591997 // Since we have proxy, should try to establish tunnel.
1998 MockWrite data_writes1[] = {
1999 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2000 "Host: www.google.com\r\n"
2001 "Proxy-Connection: keep-alive\r\n\r\n"),
2002
2003 // After calling trans->RestartWithAuth(), this is the request we should
2004 // be issuing -- the final header line contains the credentials.
2005 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2006 "Host: www.google.com\r\n"
2007 "Proxy-Connection: keep-alive\r\n"
2008 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2009
2010 MockWrite("GET / HTTP/1.1\r\n"
2011 "Host: www.google.com\r\n"
2012 "Connection: keep-alive\r\n\r\n"),
2013 };
2014
2015 // The proxy responds to the connect with a 407, using a persistent
2016 // connection.
2017 MockRead data_reads1[] = {
2018 // No credentials.
2019 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2020 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2021 MockRead("Proxy-Connection: close\r\n\r\n"),
2022
2023 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2024
2025 MockRead("HTTP/1.1 200 OK\r\n"),
2026 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502027 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062028 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592029 };
2030
2031 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2032 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072033 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062034 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592036
[email protected]49639fa2011-12-20 23:22:412037 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592038
[email protected]262eec82013-03-19 21:01:362039 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502040 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502041
[email protected]49639fa2011-12-20 23:22:412042 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592043 EXPECT_EQ(ERR_IO_PENDING, rv);
2044
2045 rv = callback1.WaitForResult();
2046 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572047 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402048 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592049 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402050 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592051 NetLog::PHASE_NONE);
2052 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402053 entries, pos,
[email protected]394816e92010-08-03 07:38:592054 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2055 NetLog::PHASE_NONE);
2056
2057 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502058 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502059 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592060 EXPECT_EQ(407, response->headers->response_code());
2061 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042062 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592063
[email protected]029c83b62013-01-24 05:28:202064 LoadTimingInfo load_timing_info;
2065 // CONNECT requests and responses are handled at the connect job level, so
2066 // the transaction does not yet have a connection.
2067 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2068
[email protected]49639fa2011-12-20 23:22:412069 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592070
[email protected]49639fa2011-12-20 23:22:412071 rv = trans->RestartWithAuth(
2072 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592073 EXPECT_EQ(ERR_IO_PENDING, rv);
2074
2075 rv = callback2.WaitForResult();
2076 EXPECT_EQ(OK, rv);
2077
2078 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502079 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592080
2081 EXPECT_TRUE(response->headers->IsKeepAlive());
2082 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502083 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592084 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2085
2086 // The password prompt info should not be set.
2087 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502088
[email protected]029c83b62013-01-24 05:28:202089 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2090 TestLoadTimingNotReusedWithPac(load_timing_info,
2091 CONNECT_TIMING_HAS_SSL_TIMES);
2092
[email protected]0b0bf032010-09-21 18:08:502093 trans.reset();
[email protected]102e27c2011-02-23 01:01:312094 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592095}
2096
[email protected]11203f012009-11-12 23:02:312097// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322098// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022099TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272100 HttpRequestInfo request;
2101 request.method = "GET";
2102 request.url = GURL("https://www.google.com/");
2103 // Ensure that proxy authentication is attempted even
2104 // when the no authentication data flag is set.
2105 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2106
[email protected]2d2697f92009-02-18 21:00:322107 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072108 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292109 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072110 session_deps_.net_log = log.bound().net_log();
2111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322112
[email protected]262eec82013-03-19 21:01:362113 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322115
[email protected]2d2697f92009-02-18 21:00:322116 // Since we have proxy, should try to establish tunnel.
2117 MockWrite data_writes1[] = {
2118 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452119 "Host: www.google.com\r\n"
2120 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322121
2122 // After calling trans->RestartWithAuth(), this is the request we should
2123 // be issuing -- the final header line contains the credentials.
2124 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2125 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452126 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322127 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2128 };
2129
2130 // The proxy responds to the connect with a 407, using a persistent
2131 // connection.
2132 MockRead data_reads1[] = {
2133 // No credentials.
2134 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2135 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2136 MockRead("Content-Length: 10\r\n\r\n"),
2137 MockRead("0123456789"),
2138
2139 // Wrong credentials (wrong password).
2140 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2141 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2142 MockRead("Content-Length: 10\r\n\r\n"),
2143 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062144 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322145 };
2146
[email protected]31a2bfe2010-02-09 08:03:392147 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2148 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072149 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322150
[email protected]49639fa2011-12-20 23:22:412151 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322152
[email protected]49639fa2011-12-20 23:22:412153 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422154 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322155
2156 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422157 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572158 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402159 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392160 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402161 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392162 NetLog::PHASE_NONE);
2163 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402164 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392165 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2166 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322167
[email protected]1c773ea12009-04-28 19:58:422168 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502169 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502170 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322171 EXPECT_TRUE(response->headers->IsKeepAlive());
2172 EXPECT_EQ(407, response->headers->response_code());
2173 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422174 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042175 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322176
[email protected]49639fa2011-12-20 23:22:412177 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322178
2179 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412180 rv = trans->RestartWithAuth(
2181 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422182 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322183
2184 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422185 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322186
2187 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502188 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502189 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322190 EXPECT_TRUE(response->headers->IsKeepAlive());
2191 EXPECT_EQ(407, response->headers->response_code());
2192 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422193 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042194 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132195
[email protected]e60e47a2010-07-14 03:37:182196 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2197 // out of scope.
[email protected]102e27c2011-02-23 01:01:312198 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322199}
2200
[email protected]a8e9b162009-03-12 00:06:442201// Test that we don't read the response body when we fail to establish a tunnel,
2202// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022203TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272204 HttpRequestInfo request;
2205 request.method = "GET";
2206 request.url = GURL("https://www.google.com/");
2207 request.load_flags = 0;
2208
[email protected]a8e9b162009-03-12 00:06:442209 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072210 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442211
[email protected]bb88e1d32013-05-03 23:11:072212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442213
[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]a8e9b162009-03-12 00:06:442216
[email protected]a8e9b162009-03-12 00:06:442217 // Since we have proxy, should try to establish tunnel.
2218 MockWrite data_writes[] = {
2219 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452220 "Host: www.google.com\r\n"
2221 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442222 };
2223
2224 // The proxy responds to the connect with a 407.
2225 MockRead data_reads[] = {
2226 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2227 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2228 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062229 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442230 };
2231
[email protected]31a2bfe2010-02-09 08:03:392232 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2233 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072234 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442235
[email protected]49639fa2011-12-20 23:22:412236 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442237
[email protected]49639fa2011-12-20 23:22:412238 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422239 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442240
2241 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422242 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442243
[email protected]1c773ea12009-04-28 19:58:422244 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502245 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442246
2247 EXPECT_TRUE(response->headers->IsKeepAlive());
2248 EXPECT_EQ(407, response->headers->response_code());
2249 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422250 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442251
2252 std::string response_data;
2253 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422254 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182255
2256 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312257 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442258}
2259
[email protected]8fdbcd22010-05-05 02:54:522260// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2261// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022262TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522263 HttpRequestInfo request;
2264 request.method = "GET";
2265 request.url = GURL("http://www.google.com/");
2266 request.load_flags = 0;
2267
[email protected]cb9bf6ca2011-01-28 13:15:272268 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072269 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272270 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272272
[email protected]8fdbcd22010-05-05 02:54:522273 MockWrite data_writes1[] = {
2274 MockWrite("GET / HTTP/1.1\r\n"
2275 "Host: www.google.com\r\n"
2276 "Connection: keep-alive\r\n\r\n"),
2277 };
2278
2279 MockRead data_reads1[] = {
2280 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2281 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2282 // Large content-length -- won't matter, as connection will be reset.
2283 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062284 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522285 };
2286
2287 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2288 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072289 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522290
[email protected]49639fa2011-12-20 23:22:412291 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522292
[email protected]49639fa2011-12-20 23:22:412293 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522294 EXPECT_EQ(ERR_IO_PENDING, rv);
2295
2296 rv = callback.WaitForResult();
2297 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2298}
2299
[email protected]7a67a8152010-11-05 18:31:102300// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2301// through a non-authenticating proxy. The request should fail with
2302// ERR_UNEXPECTED_PROXY_AUTH.
2303// Note that it is impossible to detect if an HTTP server returns a 407 through
2304// a non-authenticating proxy - there is nothing to indicate whether the
2305// response came from the proxy or the server, so it is treated as if the proxy
2306// issued the challenge.
[email protected]23e482282013-06-14 16:08:022307TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232308 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272309 HttpRequestInfo request;
2310 request.method = "GET";
2311 request.url = GURL("https://www.google.com/");
2312
[email protected]bb88e1d32013-05-03 23:11:072313 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292314 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072315 session_deps_.net_log = log.bound().net_log();
2316 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102317
[email protected]7a67a8152010-11-05 18:31:102318 // Since we have proxy, should try to establish tunnel.
2319 MockWrite data_writes1[] = {
2320 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2321 "Host: www.google.com\r\n"
2322 "Proxy-Connection: keep-alive\r\n\r\n"),
2323
2324 MockWrite("GET / HTTP/1.1\r\n"
2325 "Host: www.google.com\r\n"
2326 "Connection: keep-alive\r\n\r\n"),
2327 };
2328
2329 MockRead data_reads1[] = {
2330 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2331
2332 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2333 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2334 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062335 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102336 };
2337
2338 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2339 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072340 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062341 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072342 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102343
[email protected]49639fa2011-12-20 23:22:412344 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102345
[email protected]262eec82013-03-19 21:01:362346 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102348
[email protected]49639fa2011-12-20 23:22:412349 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102350 EXPECT_EQ(ERR_IO_PENDING, rv);
2351
2352 rv = callback1.WaitForResult();
2353 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572354 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402355 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102356 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402357 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102358 NetLog::PHASE_NONE);
2359 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402360 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102361 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2362 NetLog::PHASE_NONE);
2363}
[email protected]2df19bb2010-08-25 20:13:462364
[email protected]029c83b62013-01-24 05:28:202365// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022366TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202367 HttpRequestInfo request1;
2368 request1.method = "GET";
2369 request1.url = GURL("https://www.google.com/1");
2370
2371 HttpRequestInfo request2;
2372 request2.method = "GET";
2373 request2.url = GURL("https://www.google.com/2");
2374
2375 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072376 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202377 ProxyService::CreateFixed("PROXY myproxy:70"));
2378 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072379 session_deps_.net_log = log.bound().net_log();
2380 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202381
2382 // Since we have proxy, should try to establish tunnel.
2383 MockWrite data_writes1[] = {
2384 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2385 "Host: www.google.com\r\n"
2386 "Proxy-Connection: keep-alive\r\n\r\n"),
2387
2388 MockWrite("GET /1 HTTP/1.1\r\n"
2389 "Host: www.google.com\r\n"
2390 "Connection: keep-alive\r\n\r\n"),
2391
2392 MockWrite("GET /2 HTTP/1.1\r\n"
2393 "Host: www.google.com\r\n"
2394 "Connection: keep-alive\r\n\r\n"),
2395 };
2396
2397 // The proxy responds to the connect with a 407, using a persistent
2398 // connection.
2399 MockRead data_reads1[] = {
2400 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2401
2402 MockRead("HTTP/1.1 200 OK\r\n"),
2403 MockRead("Content-Length: 1\r\n\r\n"),
2404 MockRead(SYNCHRONOUS, "1"),
2405
2406 MockRead("HTTP/1.1 200 OK\r\n"),
2407 MockRead("Content-Length: 2\r\n\r\n"),
2408 MockRead(SYNCHRONOUS, "22"),
2409 };
2410
2411 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2412 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072413 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202414 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202416
2417 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362418 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202420
2421 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2422 EXPECT_EQ(ERR_IO_PENDING, rv);
2423
2424 rv = callback1.WaitForResult();
2425 EXPECT_EQ(OK, rv);
2426
2427 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2428 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502429 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202430 EXPECT_EQ(1, response1->headers->GetContentLength());
2431
2432 LoadTimingInfo load_timing_info1;
2433 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2434 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2435
2436 trans1.reset();
2437
2438 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362439 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502440 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202441
2442 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2443 EXPECT_EQ(ERR_IO_PENDING, rv);
2444
2445 rv = callback2.WaitForResult();
2446 EXPECT_EQ(OK, rv);
2447
2448 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2449 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502450 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202451 EXPECT_EQ(2, response2->headers->GetContentLength());
2452
2453 LoadTimingInfo load_timing_info2;
2454 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2455 TestLoadTimingReused(load_timing_info2);
2456
2457 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2458
2459 trans2.reset();
2460 session->CloseAllConnections();
2461}
2462
2463// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022464TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202465 HttpRequestInfo request1;
2466 request1.method = "GET";
2467 request1.url = GURL("https://www.google.com/1");
2468
2469 HttpRequestInfo request2;
2470 request2.method = "GET";
2471 request2.url = GURL("https://www.google.com/2");
2472
2473 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072474 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202475 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2476 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072477 session_deps_.net_log = log.bound().net_log();
2478 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202479
2480 // Since we have proxy, should try to establish tunnel.
2481 MockWrite data_writes1[] = {
2482 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2483 "Host: www.google.com\r\n"
2484 "Proxy-Connection: keep-alive\r\n\r\n"),
2485
2486 MockWrite("GET /1 HTTP/1.1\r\n"
2487 "Host: www.google.com\r\n"
2488 "Connection: keep-alive\r\n\r\n"),
2489
2490 MockWrite("GET /2 HTTP/1.1\r\n"
2491 "Host: www.google.com\r\n"
2492 "Connection: keep-alive\r\n\r\n"),
2493 };
2494
2495 // The proxy responds to the connect with a 407, using a persistent
2496 // connection.
2497 MockRead data_reads1[] = {
2498 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2499
2500 MockRead("HTTP/1.1 200 OK\r\n"),
2501 MockRead("Content-Length: 1\r\n\r\n"),
2502 MockRead(SYNCHRONOUS, "1"),
2503
2504 MockRead("HTTP/1.1 200 OK\r\n"),
2505 MockRead("Content-Length: 2\r\n\r\n"),
2506 MockRead(SYNCHRONOUS, "22"),
2507 };
2508
2509 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2510 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072511 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202512 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202514
2515 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362516 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202518
2519 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2520 EXPECT_EQ(ERR_IO_PENDING, rv);
2521
2522 rv = callback1.WaitForResult();
2523 EXPECT_EQ(OK, rv);
2524
2525 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2526 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502527 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202528 EXPECT_EQ(1, response1->headers->GetContentLength());
2529
2530 LoadTimingInfo load_timing_info1;
2531 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2532 TestLoadTimingNotReusedWithPac(load_timing_info1,
2533 CONNECT_TIMING_HAS_SSL_TIMES);
2534
2535 trans1.reset();
2536
2537 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362538 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202540
2541 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2542 EXPECT_EQ(ERR_IO_PENDING, rv);
2543
2544 rv = callback2.WaitForResult();
2545 EXPECT_EQ(OK, rv);
2546
2547 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2548 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502549 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202550 EXPECT_EQ(2, response2->headers->GetContentLength());
2551
2552 LoadTimingInfo load_timing_info2;
2553 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2554 TestLoadTimingReusedWithPac(load_timing_info2);
2555
2556 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2557
2558 trans2.reset();
2559 session->CloseAllConnections();
2560}
2561
[email protected]2df19bb2010-08-25 20:13:462562// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022563TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272564 HttpRequestInfo request;
2565 request.method = "GET";
2566 request.url = GURL("http://www.google.com/");
2567
[email protected]2df19bb2010-08-25 20:13:462568 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072569 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112570 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292571 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072572 session_deps_.net_log = log.bound().net_log();
2573 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462574
[email protected]2df19bb2010-08-25 20:13:462575 // Since we have proxy, should use full url
2576 MockWrite data_writes1[] = {
2577 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2578 "Host: www.google.com\r\n"
2579 "Proxy-Connection: keep-alive\r\n\r\n"),
2580 };
2581
2582 MockRead data_reads1[] = {
2583 MockRead("HTTP/1.1 200 OK\r\n"),
2584 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2585 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062586 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462587 };
2588
2589 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2590 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072591 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062592 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462594
[email protected]49639fa2011-12-20 23:22:412595 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462596
[email protected]262eec82013-03-19 21:01:362597 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502599
[email protected]49639fa2011-12-20 23:22:412600 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462601 EXPECT_EQ(ERR_IO_PENDING, rv);
2602
2603 rv = callback1.WaitForResult();
2604 EXPECT_EQ(OK, rv);
2605
[email protected]58e32bb2013-01-21 18:23:252606 LoadTimingInfo load_timing_info;
2607 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2608 TestLoadTimingNotReused(load_timing_info,
2609 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2610
[email protected]2df19bb2010-08-25 20:13:462611 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502612 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462613
2614 EXPECT_TRUE(response->headers->IsKeepAlive());
2615 EXPECT_EQ(200, response->headers->response_code());
2616 EXPECT_EQ(100, response->headers->GetContentLength());
2617 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2618
2619 // The password prompt info should not be set.
2620 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2621}
2622
[email protected]7642b5ae2010-09-01 20:55:172623// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022624TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272625 HttpRequestInfo request;
2626 request.method = "GET";
2627 request.url = GURL("http://www.google.com/");
2628 request.load_flags = 0;
2629
[email protected]7642b5ae2010-09-01 20:55:172630 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072631 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112632 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292633 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072634 session_deps_.net_log = log.bound().net_log();
2635 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172636
[email protected]7642b5ae2010-09-01 20:55:172637 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462638 scoped_ptr<SpdyFrame> req(
2639 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172640 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2641
[email protected]23e482282013-06-14 16:08:022642 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2643 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172644 MockRead spdy_reads[] = {
2645 CreateMockRead(*resp),
2646 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062647 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172648 };
2649
[email protected]dd54bd82012-07-19 23:44:572650 DelayedSocketData spdy_data(
2651 1, // wait for one write to finish before reading.
2652 spdy_reads, arraysize(spdy_reads),
2653 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072654 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172655
[email protected]8ddf8322012-02-23 18:08:062656 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022657 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172659
[email protected]49639fa2011-12-20 23:22:412660 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172661
[email protected]262eec82013-03-19 21:01:362662 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502664
[email protected]49639fa2011-12-20 23:22:412665 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172666 EXPECT_EQ(ERR_IO_PENDING, rv);
2667
2668 rv = callback1.WaitForResult();
2669 EXPECT_EQ(OK, rv);
2670
[email protected]58e32bb2013-01-21 18:23:252671 LoadTimingInfo load_timing_info;
2672 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2673 TestLoadTimingNotReused(load_timing_info,
2674 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2675
[email protected]7642b5ae2010-09-01 20:55:172676 const HttpResponseInfo* response = trans->GetResponseInfo();
2677 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502678 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172679 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2680
2681 std::string response_data;
2682 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232683 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172684}
2685
[email protected]dc7bd1c52010-11-12 00:01:132686// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022687TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272688 HttpRequestInfo request;
2689 request.method = "GET";
2690 request.url = GURL("http://www.google.com/");
2691 request.load_flags = 0;
2692
[email protected]79cb5c12011-09-12 13:12:042693 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072694 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042695 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292696 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072697 session_deps_.net_log = log.bound().net_log();
2698 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132699
[email protected]dc7bd1c52010-11-12 00:01:132700 // The first request will be a bare GET, the second request will be a
2701 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192702 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462703 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132704 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462705 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132706 };
[email protected]ff98d7f02012-03-22 21:44:192707 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462708 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2709 arraysize(kExtraAuthorizationHeaders) / 2,
2710 false,
2711 3,
2712 LOWEST,
2713 false));
[email protected]dc7bd1c52010-11-12 00:01:132714 MockWrite spdy_writes[] = {
2715 CreateMockWrite(*req_get, 1),
2716 CreateMockWrite(*req_get_authorization, 4),
2717 };
2718
2719 // The first response is a 407 proxy authentication challenge, and the second
2720 // response will be a 200 response since the second request includes a valid
2721 // Authorization header.
2722 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462723 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132724 };
[email protected]ff98d7f02012-03-22 21:44:192725 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022726 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132727 "407 Proxy Authentication Required",
2728 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2729 1));
[email protected]ff98d7f02012-03-22 21:44:192730 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022731 spdy_util_.ConstructSpdyBodyFrame(1, true));
2732 scoped_ptr<SpdyFrame> resp_data(
2733 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2734 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132735 MockRead spdy_reads[] = {
2736 CreateMockRead(*resp_authentication, 2),
2737 CreateMockRead(*body_authentication, 3),
2738 CreateMockRead(*resp_data, 5),
2739 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:062740 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:132741 };
2742
[email protected]dd54bd82012-07-19 23:44:572743 OrderedSocketData data(
2744 spdy_reads, arraysize(spdy_reads),
2745 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072746 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:132747
[email protected]8ddf8322012-02-23 18:08:062748 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022749 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:132751
[email protected]49639fa2011-12-20 23:22:412752 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132753
[email protected]262eec82013-03-19 21:01:362754 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:132756
[email protected]49639fa2011-12-20 23:22:412757 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:132758 EXPECT_EQ(ERR_IO_PENDING, rv);
2759
2760 rv = callback1.WaitForResult();
2761 EXPECT_EQ(OK, rv);
2762
2763 const HttpResponseInfo* const response = trans->GetResponseInfo();
2764
2765 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502766 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132767 EXPECT_EQ(407, response->headers->response_code());
2768 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042769 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132770
[email protected]49639fa2011-12-20 23:22:412771 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132772
[email protected]49639fa2011-12-20 23:22:412773 rv = trans->RestartWithAuth(
2774 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:132775 EXPECT_EQ(ERR_IO_PENDING, rv);
2776
2777 rv = callback2.WaitForResult();
2778 EXPECT_EQ(OK, rv);
2779
2780 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2781
2782 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:502783 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132784 EXPECT_EQ(200, response_restart->headers->response_code());
2785 // The password prompt info should not be set.
2786 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2787}
2788
[email protected]d9da5fe2010-10-13 22:37:162789// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:022790TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272791 HttpRequestInfo request;
2792 request.method = "GET";
2793 request.url = GURL("https://www.google.com/");
2794 request.load_flags = 0;
2795
[email protected]d9da5fe2010-10-13 22:37:162796 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072797 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112798 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292799 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072800 session_deps_.net_log = log.bound().net_log();
2801 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162802
[email protected]262eec82013-03-19 21:01:362803 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162805
[email protected]d9da5fe2010-10-13 22:37:162806 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542807 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2808 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162809 // fetch https://www.google.com/ via HTTP
2810
2811 const char get[] = "GET / HTTP/1.1\r\n"
2812 "Host: www.google.com\r\n"
2813 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192814 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:022815 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2816 scoped_ptr<SpdyFrame> conn_resp(
2817 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162818 const char resp[] = "HTTP/1.1 200 OK\r\n"
2819 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192820 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022821 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:192822 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:022823 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:192824 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:202825 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:042826
2827 MockWrite spdy_writes[] = {
2828 CreateMockWrite(*connect, 1),
2829 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:462830 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:042831 };
2832
[email protected]d9da5fe2010-10-13 22:37:162833 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062834 CreateMockRead(*conn_resp, 2, ASYNC),
2835 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2836 CreateMockRead(*wrapped_body, 6, ASYNC),
2837 CreateMockRead(*wrapped_body, 7, ASYNC),
2838 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162839 };
2840
[email protected]dd54bd82012-07-19 23:44:572841 OrderedSocketData spdy_data(
2842 spdy_reads, arraysize(spdy_reads),
2843 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072844 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162845
[email protected]8ddf8322012-02-23 18:08:062846 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022847 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062849 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:162850 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:462851 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:072852 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162853
[email protected]49639fa2011-12-20 23:22:412854 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162855
[email protected]49639fa2011-12-20 23:22:412856 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162857 EXPECT_EQ(ERR_IO_PENDING, rv);
2858
2859 rv = callback1.WaitForResult();
2860 EXPECT_EQ(OK, rv);
2861
[email protected]58e32bb2013-01-21 18:23:252862 LoadTimingInfo load_timing_info;
2863 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2864 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2865
[email protected]d9da5fe2010-10-13 22:37:162866 const HttpResponseInfo* response = trans->GetResponseInfo();
2867 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502868 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162869 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2870
2871 std::string response_data;
2872 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2873 EXPECT_EQ("1234567890", response_data);
2874}
2875
2876// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:022877TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:272878 HttpRequestInfo request;
2879 request.method = "GET";
2880 request.url = GURL("https://www.google.com/");
2881 request.load_flags = 0;
2882
[email protected]d9da5fe2010-10-13 22:37:162883 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072884 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112885 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292886 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072887 session_deps_.net_log = log.bound().net_log();
2888 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162889
[email protected]262eec82013-03-19 21:01:362890 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162892
[email protected]d9da5fe2010-10-13 22:37:162893 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542894 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2895 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162896 // fetch https://www.google.com/ via SPDY
2897 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:462898 scoped_ptr<SpdyFrame> get(
2899 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:022900 scoped_ptr<SpdyFrame> wrapped_get(
2901 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
2902 scoped_ptr<SpdyFrame> conn_resp(
2903 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2904 scoped_ptr<SpdyFrame> get_resp(
2905 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:192906 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022907 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
2908 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2909 scoped_ptr<SpdyFrame> wrapped_body(
2910 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:192911 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:202912 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:192913 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:202914 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:042915
2916 MockWrite spdy_writes[] = {
2917 CreateMockWrite(*connect, 1),
2918 CreateMockWrite(*wrapped_get, 3),
2919 CreateMockWrite(*window_update_get_resp, 5),
2920 CreateMockWrite(*window_update_body, 7),
2921 };
2922
[email protected]d9da5fe2010-10-13 22:37:162923 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062924 CreateMockRead(*conn_resp, 2, ASYNC),
2925 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2926 CreateMockRead(*wrapped_body, 6, ASYNC),
2927 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162928 };
2929
[email protected]dd54bd82012-07-19 23:44:572930 OrderedSocketData spdy_data(
2931 spdy_reads, arraysize(spdy_reads),
2932 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072933 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162934
[email protected]8ddf8322012-02-23 18:08:062935 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022936 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062938 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022939 ssl2.SetNextProto(GetParam());
2940 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:072941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162942
[email protected]49639fa2011-12-20 23:22:412943 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162944
[email protected]49639fa2011-12-20 23:22:412945 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162946 EXPECT_EQ(ERR_IO_PENDING, rv);
2947
2948 rv = callback1.WaitForResult();
2949 EXPECT_EQ(OK, rv);
2950
[email protected]58e32bb2013-01-21 18:23:252951 LoadTimingInfo load_timing_info;
2952 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2953 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2954
[email protected]d9da5fe2010-10-13 22:37:162955 const HttpResponseInfo* response = trans->GetResponseInfo();
2956 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502957 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162958 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2959
2960 std::string response_data;
2961 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232962 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:162963}
2964
2965// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022966TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:272967 HttpRequestInfo request;
2968 request.method = "GET";
2969 request.url = GURL("https://www.google.com/");
2970 request.load_flags = 0;
2971
[email protected]d9da5fe2010-10-13 22:37:162972 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072973 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112974 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292975 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072976 session_deps_.net_log = log.bound().net_log();
2977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162978
[email protected]262eec82013-03-19 21:01:362979 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502980 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162981
[email protected]d9da5fe2010-10-13 22:37:162982 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542983 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2984 LOWEST));
[email protected]c10b20852013-05-15 21:29:202985 scoped_ptr<SpdyFrame> get(
2986 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:162987
2988 MockWrite spdy_writes[] = {
2989 CreateMockWrite(*connect, 1),
2990 CreateMockWrite(*get, 3),
2991 };
2992
[email protected]23e482282013-06-14 16:08:022993 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
2994 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:162995 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062996 CreateMockRead(*resp, 2, ASYNC),
2997 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:162998 };
2999
[email protected]dd54bd82012-07-19 23:44:573000 OrderedSocketData spdy_data(
3001 spdy_reads, arraysize(spdy_reads),
3002 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073003 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163004
[email protected]8ddf8322012-02-23 18:08:063005 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023006 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073007 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063008 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023009 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163011
[email protected]49639fa2011-12-20 23:22:413012 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163013
[email protected]49639fa2011-12-20 23:22:413014 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163015 EXPECT_EQ(ERR_IO_PENDING, rv);
3016
3017 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173018 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163019
[email protected]4eddbc732012-08-09 05:40:173020 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163021}
3022
[email protected]f6c63db52013-02-02 00:35:223023// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3024// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023025TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223026 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3027 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073028 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223029 "https://proxy:70"));
3030 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073031 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223032 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073033 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223034
3035 HttpRequestInfo request1;
3036 request1.method = "GET";
3037 request1.url = GURL("https://www.google.com/");
3038 request1.load_flags = 0;
3039
3040 HttpRequestInfo request2;
3041 request2.method = "GET";
3042 request2.url = GURL("https://news.google.com/");
3043 request2.load_flags = 0;
3044
3045 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543046 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3047 LOWEST));
[email protected]23e482282013-06-14 16:08:023048 scoped_ptr<SpdyFrame> conn_resp1(
3049 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223050
3051 // Fetch https://www.google.com/ via HTTP.
3052 const char get1[] = "GET / HTTP/1.1\r\n"
3053 "Host: www.google.com\r\n"
3054 "Connection: keep-alive\r\n\r\n";
3055 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023056 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223057 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3058 "Content-Length: 1\r\n\r\n";
3059 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023060 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3061 scoped_ptr<SpdyFrame> wrapped_body1(
3062 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223063 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203064 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223065
3066 // CONNECT to news.google.com:443 via SPDY.
3067 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023068 spdy_util_.GetMethodKey(), "CONNECT",
3069 spdy_util_.GetPathKey(), "news.google.com:443",
3070 spdy_util_.GetHostKey(), "news.google.com",
3071 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223072 };
3073 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233074 spdy_util_.ConstructSpdyControlFrame(NULL,
3075 0,
3076 /*compressed*/ false,
3077 3,
3078 LOWEST,
3079 SYN_STREAM,
3080 CONTROL_FLAG_NONE,
3081 kConnectHeaders2,
3082 arraysize(kConnectHeaders2),
3083 0));
[email protected]23e482282013-06-14 16:08:023084 scoped_ptr<SpdyFrame> conn_resp2(
3085 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223086
3087 // Fetch https://news.google.com/ via HTTP.
3088 const char get2[] = "GET / HTTP/1.1\r\n"
3089 "Host: news.google.com\r\n"
3090 "Connection: keep-alive\r\n\r\n";
3091 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023092 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223093 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3094 "Content-Length: 2\r\n\r\n";
3095 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023096 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223097 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023098 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223099
3100 MockWrite spdy_writes[] = {
3101 CreateMockWrite(*connect1, 0),
3102 CreateMockWrite(*wrapped_get1, 2),
3103 CreateMockWrite(*connect2, 5),
3104 CreateMockWrite(*wrapped_get2, 7),
3105 };
3106
3107 MockRead spdy_reads[] = {
3108 CreateMockRead(*conn_resp1, 1, ASYNC),
3109 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3110 CreateMockRead(*wrapped_body1, 4, ASYNC),
3111 CreateMockRead(*conn_resp2, 6, ASYNC),
3112 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3113 CreateMockRead(*wrapped_body2, 9, ASYNC),
3114 MockRead(ASYNC, 0, 10),
3115 };
3116
3117 DeterministicSocketData spdy_data(
3118 spdy_reads, arraysize(spdy_reads),
3119 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073120 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223121
3122 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023123 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073124 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223125 SSLSocketDataProvider ssl2(ASYNC, OK);
3126 ssl2.was_npn_negotiated = false;
3127 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073128 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223129 SSLSocketDataProvider ssl3(ASYNC, OK);
3130 ssl3.was_npn_negotiated = false;
3131 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073132 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223133
3134 TestCompletionCallback callback;
3135
[email protected]262eec82013-03-19 21:01:363136 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223138 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3139 EXPECT_EQ(ERR_IO_PENDING, rv);
3140 // The first connect and request, each of their responses, and the body.
3141 spdy_data.RunFor(5);
3142
3143 rv = callback.WaitForResult();
3144 EXPECT_EQ(OK, rv);
3145
3146 LoadTimingInfo load_timing_info;
3147 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3148 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3149
3150 const HttpResponseInfo* response = trans->GetResponseInfo();
3151 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503152 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223153 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3154
3155 std::string response_data;
3156 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503157 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223158
[email protected]262eec82013-03-19 21:01:363159 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503160 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223161 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3162 EXPECT_EQ(ERR_IO_PENDING, rv);
3163
3164 // The second connect and request, each of their responses, and the body.
3165 spdy_data.RunFor(5);
3166 rv = callback.WaitForResult();
3167 EXPECT_EQ(OK, rv);
3168
3169 LoadTimingInfo load_timing_info2;
3170 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3171 // Even though the SPDY connection is reused, a new tunnelled connection has
3172 // to be created, so the socket's load timing looks like a fresh connection.
3173 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3174
3175 // The requests should have different IDs, since they each are using their own
3176 // separate stream.
3177 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3178
[email protected]90499482013-06-01 00:39:503179 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223180}
3181
3182// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3183// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023184TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223185 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3186 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073187 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223188 "https://proxy:70"));
3189 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073190 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223191 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073192 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223193
3194 HttpRequestInfo request1;
3195 request1.method = "GET";
3196 request1.url = GURL("https://www.google.com/");
3197 request1.load_flags = 0;
3198
3199 HttpRequestInfo request2;
3200 request2.method = "GET";
3201 request2.url = GURL("https://www.google.com/2");
3202 request2.load_flags = 0;
3203
3204 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543205 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3206 LOWEST));
[email protected]23e482282013-06-14 16:08:023207 scoped_ptr<SpdyFrame> conn_resp1(
3208 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223209
3210 // Fetch https://www.google.com/ via HTTP.
3211 const char get1[] = "GET / HTTP/1.1\r\n"
3212 "Host: www.google.com\r\n"
3213 "Connection: keep-alive\r\n\r\n";
3214 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023215 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223216 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3217 "Content-Length: 1\r\n\r\n";
3218 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023219 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3220 scoped_ptr<SpdyFrame> wrapped_body1(
3221 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223222 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203223 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223224
3225 // Fetch https://www.google.com/2 via HTTP.
3226 const char get2[] = "GET /2 HTTP/1.1\r\n"
3227 "Host: www.google.com\r\n"
3228 "Connection: keep-alive\r\n\r\n";
3229 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023230 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223231 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3232 "Content-Length: 2\r\n\r\n";
3233 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023234 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223235 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023236 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223237
3238 MockWrite spdy_writes[] = {
3239 CreateMockWrite(*connect1, 0),
3240 CreateMockWrite(*wrapped_get1, 2),
3241 CreateMockWrite(*wrapped_get2, 5),
3242 };
3243
3244 MockRead spdy_reads[] = {
3245 CreateMockRead(*conn_resp1, 1, ASYNC),
3246 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3247 CreateMockRead(*wrapped_body1, 4, ASYNC),
3248 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3249 CreateMockRead(*wrapped_body2, 7, ASYNC),
3250 MockRead(ASYNC, 0, 8),
3251 };
3252
3253 DeterministicSocketData spdy_data(
3254 spdy_reads, arraysize(spdy_reads),
3255 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073256 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223257
3258 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023259 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073260 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223261 SSLSocketDataProvider ssl2(ASYNC, OK);
3262 ssl2.was_npn_negotiated = false;
3263 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073264 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223265
3266 TestCompletionCallback callback;
3267
[email protected]262eec82013-03-19 21:01:363268 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223270 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3271 EXPECT_EQ(ERR_IO_PENDING, rv);
3272 // The first connect and request, each of their responses, and the body.
3273 spdy_data.RunFor(5);
3274
3275 rv = callback.WaitForResult();
3276 EXPECT_EQ(OK, rv);
3277
3278 LoadTimingInfo load_timing_info;
3279 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3280 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3281
3282 const HttpResponseInfo* response = trans->GetResponseInfo();
3283 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503284 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223285 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3286
3287 std::string response_data;
3288 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503289 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223290 trans.reset();
3291
[email protected]262eec82013-03-19 21:01:363292 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503293 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223294 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3295 EXPECT_EQ(ERR_IO_PENDING, rv);
3296
3297 // The second request, response, and body. There should not be a second
3298 // connect.
3299 spdy_data.RunFor(3);
3300 rv = callback.WaitForResult();
3301 EXPECT_EQ(OK, rv);
3302
3303 LoadTimingInfo load_timing_info2;
3304 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3305 TestLoadTimingReused(load_timing_info2);
3306
3307 // The requests should have the same ID.
3308 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3309
[email protected]90499482013-06-01 00:39:503310 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223311}
3312
3313// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3314// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023315TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223316 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3317 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073318 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223319 "https://proxy:70"));
3320 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073321 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223322 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073323 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223324
3325 HttpRequestInfo request1;
3326 request1.method = "GET";
3327 request1.url = GURL("http://www.google.com/");
3328 request1.load_flags = 0;
3329
3330 HttpRequestInfo request2;
3331 request2.method = "GET";
3332 request2.url = GURL("http://news.google.com/");
3333 request2.load_flags = 0;
3334
3335 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023336 scoped_ptr<SpdyHeaderBlock> headers(
3337 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233338 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023339 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3340 scoped_ptr<SpdyFrame> get_resp1(
3341 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3342 scoped_ptr<SpdyFrame> body1(
3343 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223344
3345 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023346 scoped_ptr<SpdyHeaderBlock> headers2(
3347 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233348 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023349 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3350 scoped_ptr<SpdyFrame> get_resp2(
3351 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3352 scoped_ptr<SpdyFrame> body2(
3353 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223354
3355 MockWrite spdy_writes[] = {
3356 CreateMockWrite(*get1, 0),
3357 CreateMockWrite(*get2, 3),
3358 };
3359
3360 MockRead spdy_reads[] = {
3361 CreateMockRead(*get_resp1, 1, ASYNC),
3362 CreateMockRead(*body1, 2, ASYNC),
3363 CreateMockRead(*get_resp2, 4, ASYNC),
3364 CreateMockRead(*body2, 5, ASYNC),
3365 MockRead(ASYNC, 0, 6),
3366 };
3367
3368 DeterministicSocketData spdy_data(
3369 spdy_reads, arraysize(spdy_reads),
3370 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073371 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223372
3373 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023374 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073375 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223376
3377 TestCompletionCallback callback;
3378
[email protected]262eec82013-03-19 21:01:363379 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223381 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3382 EXPECT_EQ(ERR_IO_PENDING, rv);
3383 spdy_data.RunFor(2);
3384
3385 rv = callback.WaitForResult();
3386 EXPECT_EQ(OK, rv);
3387
3388 LoadTimingInfo load_timing_info;
3389 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3390 TestLoadTimingNotReused(load_timing_info,
3391 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3392
3393 const HttpResponseInfo* response = trans->GetResponseInfo();
3394 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503395 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223396 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3397
3398 std::string response_data;
3399 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503400 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223401 spdy_data.RunFor(1);
3402 EXPECT_EQ(1, callback.WaitForResult());
3403 // Delete the first request, so the second one can reuse the socket.
3404 trans.reset();
3405
[email protected]262eec82013-03-19 21:01:363406 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223408 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3409 EXPECT_EQ(ERR_IO_PENDING, rv);
3410
3411 spdy_data.RunFor(2);
3412 rv = callback.WaitForResult();
3413 EXPECT_EQ(OK, rv);
3414
3415 LoadTimingInfo load_timing_info2;
3416 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3417 TestLoadTimingReused(load_timing_info2);
3418
3419 // The requests should have the same ID.
3420 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3421
[email protected]90499482013-06-01 00:39:503422 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223423 spdy_data.RunFor(1);
3424 EXPECT_EQ(2, callback.WaitForResult());
3425}
3426
[email protected]2df19bb2010-08-25 20:13:463427// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023428TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463429 HttpRequestInfo request;
3430 request.method = "GET";
3431 request.url = GURL("http://www.google.com/");
3432 // when the no authentication data flag is set.
3433 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3434
[email protected]79cb5c12011-09-12 13:12:043435 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073436 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043437 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293438 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073439 session_deps_.net_log = log.bound().net_log();
3440 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273441
[email protected]2df19bb2010-08-25 20:13:463442 // Since we have proxy, should use full url
3443 MockWrite data_writes1[] = {
3444 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3445 "Host: www.google.com\r\n"
3446 "Proxy-Connection: keep-alive\r\n\r\n"),
3447
3448 // After calling trans->RestartWithAuth(), this is the request we should
3449 // be issuing -- the final header line contains the credentials.
3450 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3451 "Host: www.google.com\r\n"
3452 "Proxy-Connection: keep-alive\r\n"
3453 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3454 };
3455
3456 // The proxy responds to the GET with a 407, using a persistent
3457 // connection.
3458 MockRead data_reads1[] = {
3459 // No credentials.
3460 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3461 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3462 MockRead("Proxy-Connection: keep-alive\r\n"),
3463 MockRead("Content-Length: 0\r\n\r\n"),
3464
3465 MockRead("HTTP/1.1 200 OK\r\n"),
3466 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3467 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063468 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463469 };
3470
3471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3472 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063474 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463476
[email protected]49639fa2011-12-20 23:22:413477 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463478
[email protected]262eec82013-03-19 21:01:363479 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503481
[email protected]49639fa2011-12-20 23:22:413482 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463483 EXPECT_EQ(ERR_IO_PENDING, rv);
3484
3485 rv = callback1.WaitForResult();
3486 EXPECT_EQ(OK, rv);
3487
[email protected]58e32bb2013-01-21 18:23:253488 LoadTimingInfo load_timing_info;
3489 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3490 TestLoadTimingNotReused(load_timing_info,
3491 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3492
[email protected]2df19bb2010-08-25 20:13:463493 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503494 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503495 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463496 EXPECT_EQ(407, response->headers->response_code());
3497 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043498 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463499
[email protected]49639fa2011-12-20 23:22:413500 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463501
[email protected]49639fa2011-12-20 23:22:413502 rv = trans->RestartWithAuth(
3503 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463504 EXPECT_EQ(ERR_IO_PENDING, rv);
3505
3506 rv = callback2.WaitForResult();
3507 EXPECT_EQ(OK, rv);
3508
[email protected]58e32bb2013-01-21 18:23:253509 load_timing_info = LoadTimingInfo();
3510 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3511 // Retrying with HTTP AUTH is considered to be reusing a socket.
3512 TestLoadTimingReused(load_timing_info);
3513
[email protected]2df19bb2010-08-25 20:13:463514 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503515 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463516
3517 EXPECT_TRUE(response->headers->IsKeepAlive());
3518 EXPECT_EQ(200, response->headers->response_code());
3519 EXPECT_EQ(100, response->headers->GetContentLength());
3520 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3521
3522 // The password prompt info should not be set.
3523 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3524}
3525
[email protected]23e482282013-06-14 16:08:023526void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083527 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423528 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083529 request.method = "GET";
3530 request.url = GURL("https://www.google.com/");
3531 request.load_flags = 0;
3532
[email protected]cb9bf6ca2011-01-28 13:15:273533 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073534 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073535 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273536
[email protected]c744cf22009-02-27 07:28:083537 // Since we have proxy, should try to establish tunnel.
3538 MockWrite data_writes[] = {
3539 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453540 "Host: www.google.com\r\n"
3541 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083542 };
3543
3544 MockRead data_reads[] = {
3545 status,
3546 MockRead("Content-Length: 10\r\n\r\n"),
3547 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063548 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083549 };
3550
[email protected]31a2bfe2010-02-09 08:03:393551 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3552 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073553 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083554
[email protected]49639fa2011-12-20 23:22:413555 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083556
[email protected]262eec82013-03-19 21:01:363557 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503559
[email protected]49639fa2011-12-20 23:22:413560 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423561 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083562
3563 rv = callback.WaitForResult();
3564 EXPECT_EQ(expected_status, rv);
3565}
3566
[email protected]23e482282013-06-14 16:08:023567void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233568 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083569 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423570 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083571}
3572
[email protected]23e482282013-06-14 16:08:023573TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083574 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3575}
3576
[email protected]23e482282013-06-14 16:08:023577TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083578 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3579}
3580
[email protected]23e482282013-06-14 16:08:023581TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083582 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3583}
3584
[email protected]23e482282013-06-14 16:08:023585TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083586 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3587}
3588
[email protected]23e482282013-06-14 16:08:023589TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083590 ConnectStatusHelper(
3591 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3592}
3593
[email protected]23e482282013-06-14 16:08:023594TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083595 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3596}
3597
[email protected]23e482282013-06-14 16:08:023598TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083599 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3600}
3601
[email protected]23e482282013-06-14 16:08:023602TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083603 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3604}
3605
[email protected]23e482282013-06-14 16:08:023606TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083607 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3608}
3609
[email protected]23e482282013-06-14 16:08:023610TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083611 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3612}
3613
[email protected]23e482282013-06-14 16:08:023614TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083615 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3616}
3617
[email protected]23e482282013-06-14 16:08:023618TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083619 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3620}
3621
[email protected]23e482282013-06-14 16:08:023622TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083623 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3624}
3625
[email protected]23e482282013-06-14 16:08:023626TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083627 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3628}
3629
[email protected]23e482282013-06-14 16:08:023630TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083631 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3632}
3633
[email protected]23e482282013-06-14 16:08:023634TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083635 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3636}
3637
[email protected]23e482282013-06-14 16:08:023638TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083639 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3640}
3641
[email protected]23e482282013-06-14 16:08:023642TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083643 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3644}
3645
[email protected]23e482282013-06-14 16:08:023646TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083647 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3648}
3649
[email protected]23e482282013-06-14 16:08:023650TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083651 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3652}
3653
[email protected]23e482282013-06-14 16:08:023654TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083655 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3656}
3657
[email protected]23e482282013-06-14 16:08:023658TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083659 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3660}
3661
[email protected]23e482282013-06-14 16:08:023662TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083663 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3664}
3665
[email protected]23e482282013-06-14 16:08:023666TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083667 ConnectStatusHelperWithExpectedStatus(
3668 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543669 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083670}
3671
[email protected]23e482282013-06-14 16:08:023672TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083673 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3674}
3675
[email protected]23e482282013-06-14 16:08:023676TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083677 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3678}
3679
[email protected]23e482282013-06-14 16:08:023680TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083681 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3682}
3683
[email protected]23e482282013-06-14 16:08:023684TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083685 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3686}
3687
[email protected]23e482282013-06-14 16:08:023688TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083689 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3690}
3691
[email protected]23e482282013-06-14 16:08:023692TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083693 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3694}
3695
[email protected]23e482282013-06-14 16:08:023696TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083697 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3698}
3699
[email protected]23e482282013-06-14 16:08:023700TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083701 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3702}
3703
[email protected]23e482282013-06-14 16:08:023704TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083705 ConnectStatusHelper(
3706 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3707}
3708
[email protected]23e482282013-06-14 16:08:023709TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083710 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3711}
3712
[email protected]23e482282013-06-14 16:08:023713TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083714 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3715}
3716
[email protected]23e482282013-06-14 16:08:023717TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083718 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3719}
3720
[email protected]23e482282013-06-14 16:08:023721TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083722 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3723}
3724
[email protected]23e482282013-06-14 16:08:023725TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083726 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3727}
3728
[email protected]23e482282013-06-14 16:08:023729TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083730 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3731}
3732
[email protected]23e482282013-06-14 16:08:023733TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083734 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3735}
3736
[email protected]038e9a32008-10-08 22:40:163737// Test the flow when both the proxy server AND origin server require
3738// authentication. Again, this uses basic auth for both since that is
3739// the simplest to mock.
[email protected]23e482282013-06-14 16:08:023740TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:273741 HttpRequestInfo request;
3742 request.method = "GET";
3743 request.url = GURL("http://www.google.com/");
3744 request.load_flags = 0;
3745
[email protected]038e9a32008-10-08 22:40:163746 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:073747 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3749
3750 scoped_ptr<HttpTransaction> trans(
3751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:163752
[email protected]f9ee6b52008-11-08 06:46:233753 MockWrite data_writes1[] = {
3754 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3755 "Host: www.google.com\r\n"
3756 "Proxy-Connection: keep-alive\r\n\r\n"),
3757 };
3758
[email protected]038e9a32008-10-08 22:40:163759 MockRead data_reads1[] = {
3760 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3761 // Give a couple authenticate options (only the middle one is actually
3762 // supported).
[email protected]22927ad2009-09-21 19:56:193763 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:163764 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3765 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3766 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3767 // Large content-length -- won't matter, as connection will be reset.
3768 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063769 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:163770 };
3771
3772 // After calling trans->RestartWithAuth() the first time, this is the
3773 // request we should be issuing -- the final header line contains the
3774 // proxy's credentials.
3775 MockWrite data_writes2[] = {
3776 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3777 "Host: www.google.com\r\n"
3778 "Proxy-Connection: keep-alive\r\n"
3779 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3780 };
3781
3782 // Now the proxy server lets the request pass through to origin server.
3783 // The origin server responds with a 401.
3784 MockRead data_reads2[] = {
3785 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3786 // Note: We are using the same realm-name as the proxy server. This is
3787 // completely valid, as realms are unique across hosts.
3788 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3789 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3790 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063791 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:163792 };
3793
3794 // After calling trans->RestartWithAuth() the second time, we should send
3795 // the credentials for both the proxy and origin server.
3796 MockWrite data_writes3[] = {
3797 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3798 "Host: www.google.com\r\n"
3799 "Proxy-Connection: keep-alive\r\n"
3800 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3801 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3802 };
3803
3804 // Lastly we get the desired content.
3805 MockRead data_reads3[] = {
3806 MockRead("HTTP/1.0 200 OK\r\n"),
3807 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3808 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063809 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:163810 };
3811
[email protected]31a2bfe2010-02-09 08:03:393812 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3813 data_writes1, arraysize(data_writes1));
3814 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3815 data_writes2, arraysize(data_writes2));
3816 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3817 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:073818 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3819 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3820 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:163821
[email protected]49639fa2011-12-20 23:22:413822 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:163823
[email protected]49639fa2011-12-20 23:22:413824 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423825 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163826
3827 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423828 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163829
[email protected]1c773ea12009-04-28 19:58:423830 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503831 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043832 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163833
[email protected]49639fa2011-12-20 23:22:413834 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:163835
[email protected]49639fa2011-12-20 23:22:413836 rv = trans->RestartWithAuth(
3837 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423838 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163839
3840 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423841 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163842
3843 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503844 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043845 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163846
[email protected]49639fa2011-12-20 23:22:413847 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:163848
[email protected]49639fa2011-12-20 23:22:413849 rv = trans->RestartWithAuth(
3850 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423851 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163852
3853 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423854 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163855
3856 response = trans->GetResponseInfo();
3857 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3858 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:163859}
[email protected]4ddaf2502008-10-23 18:26:193860
[email protected]ea9dc9a2009-09-05 00:43:323861// For the NTLM implementation using SSPI, we skip the NTLM tests since we
3862// can't hook into its internals to cause it to generate predictable NTLM
3863// authorization headers.
3864#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:293865// The NTLM authentication unit tests were generated by capturing the HTTP
3866// requests and responses using Fiddler 2 and inspecting the generated random
3867// bytes in the debugger.
3868
3869// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:023870TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:423871 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:243872 request.method = "GET";
3873 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:543874
3875 // Ensure load is not disrupted by flags which suppress behaviour specific
3876 // to other auth schemes.
3877 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:243878
[email protected]cb9bf6ca2011-01-28 13:15:273879 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
3880 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:073881 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273882
[email protected]3f918782009-02-28 01:29:243883 MockWrite data_writes1[] = {
3884 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3885 "Host: 172.22.68.17\r\n"
3886 "Connection: keep-alive\r\n\r\n"),
3887 };
3888
3889 MockRead data_reads1[] = {
3890 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043891 // Negotiate and NTLM are often requested together. However, we only want
3892 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3893 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:243894 MockRead("WWW-Authenticate: NTLM\r\n"),
3895 MockRead("Connection: close\r\n"),
3896 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363897 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243898 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:063899 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:243900 };
3901
3902 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:223903 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:243904 // request we should be issuing -- the final header line contains a Type
3905 // 1 message.
3906 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3907 "Host: 172.22.68.17\r\n"
3908 "Connection: keep-alive\r\n"
3909 "Authorization: NTLM "
3910 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3911
3912 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3913 // (the credentials for the origin server). The second request continues
3914 // on the same connection.
3915 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3916 "Host: 172.22.68.17\r\n"
3917 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:293918 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3919 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3920 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
3921 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
3922 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243923 };
3924
3925 MockRead data_reads2[] = {
3926 // The origin server responds with a Type 2 message.
3927 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3928 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:293929 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:243930 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3931 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3932 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3933 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3934 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3935 "BtAAAAAAA=\r\n"),
3936 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363937 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243938 MockRead("You are not authorized to view this page\r\n"),
3939
3940 // Lastly we get the desired content.
3941 MockRead("HTTP/1.1 200 OK\r\n"),
3942 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3943 MockRead("Content-Length: 13\r\n\r\n"),
3944 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:063945 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:243946 };
3947
[email protected]31a2bfe2010-02-09 08:03:393948 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3949 data_writes1, arraysize(data_writes1));
3950 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3951 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3953 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:243954
[email protected]49639fa2011-12-20 23:22:413955 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:243956
[email protected]262eec82013-03-19 21:01:363957 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503958 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503959
[email protected]49639fa2011-12-20 23:22:413960 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423961 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243962
3963 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423964 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243965
[email protected]0757e7702009-03-27 04:00:223966 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3967
[email protected]1c773ea12009-04-28 19:58:423968 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043969 ASSERT_FALSE(response == NULL);
3970 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:243971
[email protected]49639fa2011-12-20 23:22:413972 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:253973
[email protected]f3cf9802011-10-28 18:44:583974 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:413975 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:253976 EXPECT_EQ(ERR_IO_PENDING, rv);
3977
3978 rv = callback2.WaitForResult();
3979 EXPECT_EQ(OK, rv);
3980
3981 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3982
3983 response = trans->GetResponseInfo();
3984 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:253985 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3986
[email protected]49639fa2011-12-20 23:22:413987 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:243988
[email protected]49639fa2011-12-20 23:22:413989 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423990 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243991
[email protected]0757e7702009-03-27 04:00:223992 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423993 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243994
3995 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503996 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:243997 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3998 EXPECT_EQ(13, response->headers->GetContentLength());
3999}
4000
[email protected]385a4672009-03-11 22:21:294001// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024002TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424003 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294004 request.method = "GET";
4005 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4006 request.load_flags = 0;
4007
[email protected]cb9bf6ca2011-01-28 13:15:274008 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4009 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074010 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274011
[email protected]385a4672009-03-11 22:21:294012 MockWrite data_writes1[] = {
4013 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4014 "Host: 172.22.68.17\r\n"
4015 "Connection: keep-alive\r\n\r\n"),
4016 };
4017
4018 MockRead data_reads1[] = {
4019 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044020 // Negotiate and NTLM are often requested together. However, we only want
4021 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4022 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294023 MockRead("WWW-Authenticate: NTLM\r\n"),
4024 MockRead("Connection: close\r\n"),
4025 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364026 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294027 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064028 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294029 };
4030
4031 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224032 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294033 // request we should be issuing -- the final header line contains a Type
4034 // 1 message.
4035 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4036 "Host: 172.22.68.17\r\n"
4037 "Connection: keep-alive\r\n"
4038 "Authorization: NTLM "
4039 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4040
4041 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4042 // (the credentials for the origin server). The second request continues
4043 // on the same connection.
4044 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4045 "Host: 172.22.68.17\r\n"
4046 "Connection: keep-alive\r\n"
4047 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4048 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4049 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4050 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4051 "4Ww7b7E=\r\n\r\n"),
4052 };
4053
4054 MockRead data_reads2[] = {
4055 // The origin server responds with a Type 2 message.
4056 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4057 MockRead("WWW-Authenticate: NTLM "
4058 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4059 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4060 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4061 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4062 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4063 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4064 "BtAAAAAAA=\r\n"),
4065 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364066 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294067 MockRead("You are not authorized to view this page\r\n"),
4068
4069 // Wrong password.
4070 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294071 MockRead("WWW-Authenticate: NTLM\r\n"),
4072 MockRead("Connection: close\r\n"),
4073 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364074 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294075 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064076 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294077 };
4078
4079 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224080 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294081 // request we should be issuing -- the final header line contains a Type
4082 // 1 message.
4083 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4084 "Host: 172.22.68.17\r\n"
4085 "Connection: keep-alive\r\n"
4086 "Authorization: NTLM "
4087 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4088
4089 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4090 // (the credentials for the origin server). The second request continues
4091 // on the same connection.
4092 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4093 "Host: 172.22.68.17\r\n"
4094 "Connection: keep-alive\r\n"
4095 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4096 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4097 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4098 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4099 "+4MUm7c=\r\n\r\n"),
4100 };
4101
4102 MockRead data_reads3[] = {
4103 // The origin server responds with a Type 2 message.
4104 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4105 MockRead("WWW-Authenticate: NTLM "
4106 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4107 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4108 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4109 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4110 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4111 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4112 "BtAAAAAAA=\r\n"),
4113 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364114 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294115 MockRead("You are not authorized to view this page\r\n"),
4116
4117 // Lastly we get the desired content.
4118 MockRead("HTTP/1.1 200 OK\r\n"),
4119 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4120 MockRead("Content-Length: 13\r\n\r\n"),
4121 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064122 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294123 };
4124
[email protected]31a2bfe2010-02-09 08:03:394125 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4126 data_writes1, arraysize(data_writes1));
4127 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4128 data_writes2, arraysize(data_writes2));
4129 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4130 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074131 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4132 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4133 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294134
[email protected]49639fa2011-12-20 23:22:414135 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294136
[email protected]262eec82013-03-19 21:01:364137 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504138 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504139
[email protected]49639fa2011-12-20 23:22:414140 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424141 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294142
4143 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424144 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294145
[email protected]0757e7702009-03-27 04:00:224146 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294147
[email protected]1c773ea12009-04-28 19:58:424148 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504149 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044150 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294151
[email protected]49639fa2011-12-20 23:22:414152 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294153
[email protected]0757e7702009-03-27 04:00:224154 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584155 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414156 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424157 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294158
[email protected]10af5fe72011-01-31 16:17:254159 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424160 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294161
[email protected]0757e7702009-03-27 04:00:224162 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414163 TestCompletionCallback callback3;
4164 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424165 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254166 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424167 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224168 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4169
4170 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044171 ASSERT_FALSE(response == NULL);
4172 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224173
[email protected]49639fa2011-12-20 23:22:414174 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224175
4176 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584177 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414178 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254179 EXPECT_EQ(ERR_IO_PENDING, rv);
4180
4181 rv = callback4.WaitForResult();
4182 EXPECT_EQ(OK, rv);
4183
4184 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4185
[email protected]49639fa2011-12-20 23:22:414186 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254187
4188 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414189 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424190 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224191
4192 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424193 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224194
[email protected]385a4672009-03-11 22:21:294195 response = trans->GetResponseInfo();
4196 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4197 EXPECT_EQ(13, response->headers->GetContentLength());
4198}
[email protected]ea9dc9a2009-09-05 00:43:324199#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294200
[email protected]4ddaf2502008-10-23 18:26:194201// Test reading a server response which has only headers, and no body.
4202// After some maximum number of bytes is consumed, the transaction should
4203// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024204TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424205 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194206 request.method = "GET";
4207 request.url = GURL("http://www.google.com/");
4208 request.load_flags = 0;
4209
[email protected]3fe8d2f82013-10-17 08:56:074210 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274211 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274213
[email protected]b75b7b2f2009-10-06 00:54:534214 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434215 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534216 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194217
4218 MockRead data_reads[] = {
4219 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064220 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194221 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064222 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194223 };
[email protected]31a2bfe2010-02-09 08:03:394224 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074225 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194226
[email protected]49639fa2011-12-20 23:22:414227 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194228
[email protected]49639fa2011-12-20 23:22:414229 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424230 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194231
4232 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424233 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194234
[email protected]1c773ea12009-04-28 19:58:424235 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194236 EXPECT_TRUE(response == NULL);
4237}
[email protected]f4e426b2008-11-05 00:24:494238
4239// Make sure that we don't try to reuse a TCPClientSocket when failing to
4240// establish tunnel.
4241// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024242TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234243 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274244 HttpRequestInfo request;
4245 request.method = "GET";
4246 request.url = GURL("https://www.google.com/");
4247 request.load_flags = 0;
4248
[email protected]f4e426b2008-11-05 00:24:494249 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074250 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014251
[email protected]bb88e1d32013-05-03 23:11:074252 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494253
[email protected]262eec82013-03-19 21:01:364254 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494256
[email protected]f4e426b2008-11-05 00:24:494257 // Since we have proxy, should try to establish tunnel.
4258 MockWrite data_writes1[] = {
4259 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454260 "Host: www.google.com\r\n"
4261 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494262 };
4263
[email protected]77848d12008-11-14 00:00:224264 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494265 // connection. Usually a proxy would return 501 (not implemented),
4266 // or 200 (tunnel established).
4267 MockRead data_reads1[] = {
4268 MockRead("HTTP/1.1 404 Not Found\r\n"),
4269 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064270 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494271 };
4272
[email protected]31a2bfe2010-02-09 08:03:394273 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4274 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074275 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494276
[email protected]49639fa2011-12-20 23:22:414277 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494278
[email protected]49639fa2011-12-20 23:22:414279 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424280 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494281
4282 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424283 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494284
[email protected]1c773ea12009-04-28 19:58:424285 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084286 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494287
[email protected]b4404c02009-04-10 16:38:524288 // Empty the current queue. This is necessary because idle sockets are
4289 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344290 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524291
[email protected]f4e426b2008-11-05 00:24:494292 // We now check to make sure the TCPClientSocket was not added back to
4293 // the pool.
[email protected]90499482013-06-01 00:39:504294 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494295 trans.reset();
[email protected]2da659e2013-05-23 20:51:344296 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494297 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504298 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494299}
[email protected]372d34a2008-11-05 21:30:514300
[email protected]1b157c02009-04-21 01:55:404301// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024302TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424303 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404304 request.method = "GET";
4305 request.url = GURL("http://www.google.com/");
4306 request.load_flags = 0;
4307
[email protected]bb88e1d32013-05-03 23:11:074308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274309
[email protected]262eec82013-03-19 21:01:364310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274312
[email protected]1b157c02009-04-21 01:55:404313 MockRead data_reads[] = {
4314 // A part of the response body is received with the response headers.
4315 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4316 // The rest of the response body is received in two parts.
4317 MockRead("lo"),
4318 MockRead(" world"),
4319 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064320 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404321 };
4322
[email protected]31a2bfe2010-02-09 08:03:394323 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074324 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404325
[email protected]49639fa2011-12-20 23:22:414326 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404327
[email protected]49639fa2011-12-20 23:22:414328 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424329 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404330
4331 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424332 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404333
[email protected]1c773ea12009-04-28 19:58:424334 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504335 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404336
[email protected]90499482013-06-01 00:39:504337 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404338 std::string status_line = response->headers->GetStatusLine();
4339 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4340
[email protected]90499482013-06-01 00:39:504341 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404342
4343 std::string response_data;
4344 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424345 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404346 EXPECT_EQ("hello world", response_data);
4347
4348 // Empty the current queue. This is necessary because idle sockets are
4349 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344350 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404351
4352 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504353 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404354}
4355
[email protected]76a505b2010-08-25 06:23:004356// Make sure that we recycle a SSL socket after reading all of the response
4357// body.
[email protected]23e482282013-06-14 16:08:024358TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004359 HttpRequestInfo request;
4360 request.method = "GET";
4361 request.url = GURL("https://www.google.com/");
4362 request.load_flags = 0;
4363
4364 MockWrite data_writes[] = {
4365 MockWrite("GET / HTTP/1.1\r\n"
4366 "Host: www.google.com\r\n"
4367 "Connection: keep-alive\r\n\r\n"),
4368 };
4369
4370 MockRead data_reads[] = {
4371 MockRead("HTTP/1.1 200 OK\r\n"),
4372 MockRead("Content-Length: 11\r\n\r\n"),
4373 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064374 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004375 };
4376
[email protected]8ddf8322012-02-23 18:08:064377 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004379
4380 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4381 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074382 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004383
[email protected]49639fa2011-12-20 23:22:414384 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004385
[email protected]bb88e1d32013-05-03 23:11:074386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364387 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004389
[email protected]49639fa2011-12-20 23:22:414390 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004391
4392 EXPECT_EQ(ERR_IO_PENDING, rv);
4393 EXPECT_EQ(OK, callback.WaitForResult());
4394
4395 const HttpResponseInfo* response = trans->GetResponseInfo();
4396 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504397 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004398 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4399
[email protected]90499482013-06-01 00:39:504400 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004401
4402 std::string response_data;
4403 rv = ReadTransaction(trans.get(), &response_data);
4404 EXPECT_EQ(OK, rv);
4405 EXPECT_EQ("hello world", response_data);
4406
4407 // Empty the current queue. This is necessary because idle sockets are
4408 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344409 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004410
4411 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504412 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004413}
4414
4415// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4416// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024417TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004418 HttpRequestInfo request;
4419 request.method = "GET";
4420 request.url = GURL("https://www.google.com/");
4421 request.load_flags = 0;
4422
4423 MockWrite data_writes[] = {
4424 MockWrite("GET / HTTP/1.1\r\n"
4425 "Host: www.google.com\r\n"
4426 "Connection: keep-alive\r\n\r\n"),
4427 MockWrite("GET / HTTP/1.1\r\n"
4428 "Host: www.google.com\r\n"
4429 "Connection: keep-alive\r\n\r\n"),
4430 };
4431
4432 MockRead data_reads[] = {
4433 MockRead("HTTP/1.1 200 OK\r\n"),
4434 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064435 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004436 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064437 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004438 };
4439
[email protected]8ddf8322012-02-23 18:08:064440 SSLSocketDataProvider ssl(ASYNC, OK);
4441 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074442 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4443 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004444
4445 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4446 data_writes, arraysize(data_writes));
4447 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4448 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074449 session_deps_.socket_factory->AddSocketDataProvider(&data);
4450 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004451
[email protected]49639fa2011-12-20 23:22:414452 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004453
[email protected]bb88e1d32013-05-03 23:11:074454 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364455 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504456 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004457
[email protected]49639fa2011-12-20 23:22:414458 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004459
4460 EXPECT_EQ(ERR_IO_PENDING, rv);
4461 EXPECT_EQ(OK, callback.WaitForResult());
4462
4463 const HttpResponseInfo* response = trans->GetResponseInfo();
4464 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504465 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004466 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4467
[email protected]90499482013-06-01 00:39:504468 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004469
4470 std::string response_data;
4471 rv = ReadTransaction(trans.get(), &response_data);
4472 EXPECT_EQ(OK, rv);
4473 EXPECT_EQ("hello world", response_data);
4474
4475 // Empty the current queue. This is necessary because idle sockets are
4476 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344477 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004478
4479 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504480 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004481
4482 // Now start the second transaction, which should reuse the previous socket.
4483
[email protected]90499482013-06-01 00:39:504484 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004485
[email protected]49639fa2011-12-20 23:22:414486 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004487
4488 EXPECT_EQ(ERR_IO_PENDING, rv);
4489 EXPECT_EQ(OK, callback.WaitForResult());
4490
4491 response = trans->GetResponseInfo();
4492 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504493 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004494 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4495
[email protected]90499482013-06-01 00:39:504496 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004497
4498 rv = ReadTransaction(trans.get(), &response_data);
4499 EXPECT_EQ(OK, rv);
4500 EXPECT_EQ("hello world", response_data);
4501
4502 // Empty the current queue. This is necessary because idle sockets are
4503 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344504 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004505
4506 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504507 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004508}
4509
[email protected]b4404c02009-04-10 16:38:524510// Make sure that we recycle a socket after a zero-length response.
4511// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024512TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424513 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524514 request.method = "GET";
4515 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4516 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4517 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4518 "rt=prt.2642,ol.2649,xjs.2951");
4519 request.load_flags = 0;
4520
[email protected]bb88e1d32013-05-03 23:11:074521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274522
[email protected]262eec82013-03-19 21:01:364523 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504524 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274525
[email protected]b4404c02009-04-10 16:38:524526 MockRead data_reads[] = {
4527 MockRead("HTTP/1.1 204 No Content\r\n"
4528 "Content-Length: 0\r\n"
4529 "Content-Type: text/html\r\n\r\n"),
4530 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064531 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524532 };
4533
[email protected]31a2bfe2010-02-09 08:03:394534 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074535 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524536
[email protected]49639fa2011-12-20 23:22:414537 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524538
[email protected]49639fa2011-12-20 23:22:414539 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424540 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524541
4542 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424543 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524544
[email protected]1c773ea12009-04-28 19:58:424545 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504546 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524547
[email protected]90499482013-06-01 00:39:504548 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524549 std::string status_line = response->headers->GetStatusLine();
4550 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4551
[email protected]90499482013-06-01 00:39:504552 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524553
4554 std::string response_data;
4555 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424556 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524557 EXPECT_EQ("", response_data);
4558
4559 // Empty the current queue. This is necessary because idle sockets are
4560 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344561 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524562
4563 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504564 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524565}
4566
[email protected]23e482282013-06-14 16:08:024567TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064568 ScopedVector<UploadElementReader> element_readers;
4569 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204570 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274571
[email protected]1c773ea12009-04-28 19:58:424572 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514573 // Transaction 1: a GET request that succeeds. The socket is recycled
4574 // after use.
4575 request[0].method = "GET";
4576 request[0].url = GURL("http://www.google.com/");
4577 request[0].load_flags = 0;
4578 // Transaction 2: a POST request. Reuses the socket kept alive from
4579 // transaction 1. The first attempts fails when writing the POST data.
4580 // This causes the transaction to retry with a new socket. The second
4581 // attempt succeeds.
4582 request[1].method = "POST";
4583 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274584 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514585 request[1].load_flags = 0;
4586
[email protected]bb88e1d32013-05-03 23:11:074587 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514588
4589 // The first socket is used for transaction 1 and the first attempt of
4590 // transaction 2.
4591
4592 // The response of transaction 1.
4593 MockRead data_reads1[] = {
4594 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4595 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064596 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514597 };
4598 // The mock write results of transaction 1 and the first attempt of
4599 // transaction 2.
4600 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064601 MockWrite(SYNCHRONOUS, 64), // GET
4602 MockWrite(SYNCHRONOUS, 93), // POST
4603 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514604 };
[email protected]31a2bfe2010-02-09 08:03:394605 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4606 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514607
4608 // The second socket is used for the second attempt of transaction 2.
4609
4610 // The response of transaction 2.
4611 MockRead data_reads2[] = {
4612 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4613 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064614 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514615 };
4616 // The mock write results of the second attempt of transaction 2.
4617 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064618 MockWrite(SYNCHRONOUS, 93), // POST
4619 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514620 };
[email protected]31a2bfe2010-02-09 08:03:394621 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4622 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514623
[email protected]bb88e1d32013-05-03 23:11:074624 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4625 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514626
4627 const char* kExpectedResponseData[] = {
4628 "hello world", "welcome"
4629 };
4630
4631 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424632 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514634
[email protected]49639fa2011-12-20 23:22:414635 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514636
[email protected]49639fa2011-12-20 23:22:414637 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424638 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514639
4640 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424641 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514642
[email protected]1c773ea12009-04-28 19:58:424643 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504644 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514645
[email protected]90499482013-06-01 00:39:504646 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514647 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4648
4649 std::string response_data;
4650 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424651 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514652 EXPECT_EQ(kExpectedResponseData[i], response_data);
4653 }
4654}
[email protected]f9ee6b52008-11-08 06:46:234655
4656// Test the request-challenge-retry sequence for basic auth when there is
4657// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164658// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024659TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424660 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234661 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294662 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414663 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294664
[email protected]3fe8d2f82013-10-17 08:56:074665 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274666 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274668
[email protected]a97cca42009-08-14 01:00:294669 // The password contains an escaped character -- for this test to pass it
4670 // will need to be unescaped by HttpNetworkTransaction.
4671 EXPECT_EQ("b%40r", request.url.password());
4672
[email protected]f9ee6b52008-11-08 06:46:234673 MockWrite data_writes1[] = {
4674 MockWrite("GET / HTTP/1.1\r\n"
4675 "Host: www.google.com\r\n"
4676 "Connection: keep-alive\r\n\r\n"),
4677 };
4678
4679 MockRead data_reads1[] = {
4680 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4681 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4682 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064683 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234684 };
4685
[email protected]2262e3a2012-05-22 16:08:164686 // After the challenge above, the transaction will be restarted using the
4687 // identity from the url (foo, b@r) to answer the challenge.
4688 MockWrite data_writes2[] = {
4689 MockWrite("GET / HTTP/1.1\r\n"
4690 "Host: www.google.com\r\n"
4691 "Connection: keep-alive\r\n"
4692 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4693 };
4694
4695 MockRead data_reads2[] = {
4696 MockRead("HTTP/1.0 200 OK\r\n"),
4697 MockRead("Content-Length: 100\r\n\r\n"),
4698 MockRead(SYNCHRONOUS, OK),
4699 };
4700
[email protected]31a2bfe2010-02-09 08:03:394701 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4702 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164703 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4704 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074705 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4706 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234707
[email protected]49639fa2011-12-20 23:22:414708 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414709 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424710 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234711 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424712 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164713 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4714
4715 TestCompletionCallback callback2;
4716 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4717 EXPECT_EQ(ERR_IO_PENDING, rv);
4718 rv = callback2.WaitForResult();
4719 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224720 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4721
[email protected]2262e3a2012-05-22 16:08:164722 const HttpResponseInfo* response = trans->GetResponseInfo();
4723 ASSERT_TRUE(response != NULL);
4724
4725 // There is no challenge info, since the identity in URL worked.
4726 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4727
4728 EXPECT_EQ(100, response->headers->GetContentLength());
4729
4730 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344731 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164732}
4733
4734// Test the request-challenge-retry sequence for basic auth when there is an
4735// incorrect identity in the URL. The identity from the URL should be used only
4736// once.
[email protected]23e482282013-06-14 16:08:024737TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164738 HttpRequestInfo request;
4739 request.method = "GET";
4740 // Note: the URL has a username:password in it. The password "baz" is
4741 // wrong (should be "bar").
4742 request.url = GURL("http://foo:[email protected]/");
4743
4744 request.load_flags = LOAD_NORMAL;
4745
[email protected]3fe8d2f82013-10-17 08:56:074746 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:164747 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074748 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:164749
4750 MockWrite data_writes1[] = {
4751 MockWrite("GET / HTTP/1.1\r\n"
4752 "Host: www.google.com\r\n"
4753 "Connection: keep-alive\r\n\r\n"),
4754 };
4755
4756 MockRead data_reads1[] = {
4757 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4758 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4759 MockRead("Content-Length: 10\r\n\r\n"),
4760 MockRead(SYNCHRONOUS, ERR_FAILED),
4761 };
4762
4763 // After the challenge above, the transaction will be restarted using the
4764 // identity from the url (foo, baz) to answer the challenge.
4765 MockWrite data_writes2[] = {
4766 MockWrite("GET / HTTP/1.1\r\n"
4767 "Host: www.google.com\r\n"
4768 "Connection: keep-alive\r\n"
4769 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4770 };
4771
4772 MockRead data_reads2[] = {
4773 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4774 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4775 MockRead("Content-Length: 10\r\n\r\n"),
4776 MockRead(SYNCHRONOUS, ERR_FAILED),
4777 };
4778
4779 // After the challenge above, the transaction will be restarted using the
4780 // identity supplied by the user (foo, bar) to answer the challenge.
4781 MockWrite data_writes3[] = {
4782 MockWrite("GET / HTTP/1.1\r\n"
4783 "Host: www.google.com\r\n"
4784 "Connection: keep-alive\r\n"
4785 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4786 };
4787
4788 MockRead data_reads3[] = {
4789 MockRead("HTTP/1.0 200 OK\r\n"),
4790 MockRead("Content-Length: 100\r\n\r\n"),
4791 MockRead(SYNCHRONOUS, OK),
4792 };
4793
4794 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4795 data_writes1, arraysize(data_writes1));
4796 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4797 data_writes2, arraysize(data_writes2));
4798 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4799 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074800 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4801 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4802 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:164803
4804 TestCompletionCallback callback1;
4805
4806 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4807 EXPECT_EQ(ERR_IO_PENDING, rv);
4808
4809 rv = callback1.WaitForResult();
4810 EXPECT_EQ(OK, rv);
4811
4812 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4813 TestCompletionCallback callback2;
4814 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4815 EXPECT_EQ(ERR_IO_PENDING, rv);
4816 rv = callback2.WaitForResult();
4817 EXPECT_EQ(OK, rv);
4818 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4819
4820 const HttpResponseInfo* response = trans->GetResponseInfo();
4821 ASSERT_TRUE(response != NULL);
4822 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4823
4824 TestCompletionCallback callback3;
4825 rv = trans->RestartWithAuth(
4826 AuthCredentials(kFoo, kBar), callback3.callback());
4827 EXPECT_EQ(ERR_IO_PENDING, rv);
4828 rv = callback3.WaitForResult();
4829 EXPECT_EQ(OK, rv);
4830 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4831
4832 response = trans->GetResponseInfo();
4833 ASSERT_TRUE(response != NULL);
4834
4835 // There is no challenge info, since the identity worked.
4836 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4837
4838 EXPECT_EQ(100, response->headers->GetContentLength());
4839
[email protected]ea9dc9a2009-09-05 00:43:324840 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344841 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:324842}
4843
[email protected]2217aa22013-10-11 03:03:544844
4845// Test the request-challenge-retry sequence for basic auth when there is a
4846// correct identity in the URL, but its use is being suppressed. The identity
4847// from the URL should never be used.
4848TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
4849 HttpRequestInfo request;
4850 request.method = "GET";
4851 request.url = GURL("http://foo:[email protected]/");
4852 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
4853
[email protected]3fe8d2f82013-10-17 08:56:074854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:544855 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:544857
4858 MockWrite data_writes1[] = {
4859 MockWrite("GET / HTTP/1.1\r\n"
4860 "Host: www.google.com\r\n"
4861 "Connection: keep-alive\r\n\r\n"),
4862 };
4863
4864 MockRead data_reads1[] = {
4865 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4866 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4867 MockRead("Content-Length: 10\r\n\r\n"),
4868 MockRead(SYNCHRONOUS, ERR_FAILED),
4869 };
4870
4871 // After the challenge above, the transaction will be restarted using the
4872 // identity supplied by the user, not the one in the URL, to answer the
4873 // challenge.
4874 MockWrite data_writes3[] = {
4875 MockWrite("GET / HTTP/1.1\r\n"
4876 "Host: www.google.com\r\n"
4877 "Connection: keep-alive\r\n"
4878 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4879 };
4880
4881 MockRead data_reads3[] = {
4882 MockRead("HTTP/1.0 200 OK\r\n"),
4883 MockRead("Content-Length: 100\r\n\r\n"),
4884 MockRead(SYNCHRONOUS, OK),
4885 };
4886
4887 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4888 data_writes1, arraysize(data_writes1));
4889 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4890 data_writes3, arraysize(data_writes3));
4891 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4892 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4893
4894 TestCompletionCallback callback1;
4895 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4896 EXPECT_EQ(ERR_IO_PENDING, rv);
4897 rv = callback1.WaitForResult();
4898 EXPECT_EQ(OK, rv);
4899 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4900
4901 const HttpResponseInfo* response = trans->GetResponseInfo();
4902 ASSERT_TRUE(response != NULL);
4903 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4904
4905 TestCompletionCallback callback3;
4906 rv = trans->RestartWithAuth(
4907 AuthCredentials(kFoo, kBar), callback3.callback());
4908 EXPECT_EQ(ERR_IO_PENDING, rv);
4909 rv = callback3.WaitForResult();
4910 EXPECT_EQ(OK, rv);
4911 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4912
4913 response = trans->GetResponseInfo();
4914 ASSERT_TRUE(response != NULL);
4915
4916 // There is no challenge info, since the identity worked.
4917 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4918 EXPECT_EQ(100, response->headers->GetContentLength());
4919
4920 // Empty the current queue.
4921 base::MessageLoop::current()->RunUntilIdle();
4922}
4923
[email protected]f9ee6b52008-11-08 06:46:234924// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:024925TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:074926 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:234927
4928 // Transaction 1: authenticate (foo, bar) on MyRealm1
4929 {
[email protected]1c773ea12009-04-28 19:58:424930 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234931 request.method = "GET";
4932 request.url = GURL("http://www.google.com/x/y/z");
4933 request.load_flags = 0;
4934
[email protected]262eec82013-03-19 21:01:364935 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504936 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274937
[email protected]f9ee6b52008-11-08 06:46:234938 MockWrite data_writes1[] = {
4939 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4940 "Host: www.google.com\r\n"
4941 "Connection: keep-alive\r\n\r\n"),
4942 };
4943
4944 MockRead data_reads1[] = {
4945 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4946 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4947 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064948 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234949 };
4950
4951 // Resend with authorization (username=foo, password=bar)
4952 MockWrite data_writes2[] = {
4953 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4954 "Host: www.google.com\r\n"
4955 "Connection: keep-alive\r\n"
4956 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4957 };
4958
4959 // Sever accepts the authorization.
4960 MockRead data_reads2[] = {
4961 MockRead("HTTP/1.0 200 OK\r\n"),
4962 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064963 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234964 };
4965
[email protected]31a2bfe2010-02-09 08:03:394966 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4967 data_writes1, arraysize(data_writes1));
4968 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4969 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074970 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4971 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234972
[email protected]49639fa2011-12-20 23:22:414973 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234974
[email protected]49639fa2011-12-20 23:22:414975 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424976 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234977
4978 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424979 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234980
[email protected]1c773ea12009-04-28 19:58:424981 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504982 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044983 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:234984
[email protected]49639fa2011-12-20 23:22:414985 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234986
[email protected]49639fa2011-12-20 23:22:414987 rv = trans->RestartWithAuth(
4988 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424989 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234990
4991 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424992 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234993
4994 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504995 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234996 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4997 EXPECT_EQ(100, response->headers->GetContentLength());
4998 }
4999
5000 // ------------------------------------------------------------------------
5001
5002 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5003 {
[email protected]1c773ea12009-04-28 19:58:425004 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235005 request.method = "GET";
5006 // Note that Transaction 1 was at /x/y/z, so this is in the same
5007 // protection space as MyRealm1.
5008 request.url = GURL("http://www.google.com/x/y/a/b");
5009 request.load_flags = 0;
5010
[email protected]262eec82013-03-19 21:01:365011 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505012 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275013
[email protected]f9ee6b52008-11-08 06:46:235014 MockWrite data_writes1[] = {
5015 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5016 "Host: www.google.com\r\n"
5017 "Connection: keep-alive\r\n"
5018 // Send preemptive authorization for MyRealm1
5019 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5020 };
5021
5022 // The server didn't like the preemptive authorization, and
5023 // challenges us for a different realm (MyRealm2).
5024 MockRead data_reads1[] = {
5025 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5026 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5027 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065028 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235029 };
5030
5031 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5032 MockWrite data_writes2[] = {
5033 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5034 "Host: www.google.com\r\n"
5035 "Connection: keep-alive\r\n"
5036 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5037 };
5038
5039 // Sever accepts the authorization.
5040 MockRead data_reads2[] = {
5041 MockRead("HTTP/1.0 200 OK\r\n"),
5042 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065043 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235044 };
5045
[email protected]31a2bfe2010-02-09 08:03:395046 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5047 data_writes1, arraysize(data_writes1));
5048 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5049 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075050 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5051 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235052
[email protected]49639fa2011-12-20 23:22:415053 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235054
[email protected]49639fa2011-12-20 23:22:415055 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425056 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235057
5058 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425059 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235060
[email protected]1c773ea12009-04-28 19:58:425061 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505062 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045063 ASSERT_TRUE(response->auth_challenge.get());
5064 EXPECT_FALSE(response->auth_challenge->is_proxy);
5065 EXPECT_EQ("www.google.com:80",
5066 response->auth_challenge->challenger.ToString());
5067 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5068 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235069
[email protected]49639fa2011-12-20 23:22:415070 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235071
[email protected]49639fa2011-12-20 23:22:415072 rv = trans->RestartWithAuth(
5073 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425074 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235075
5076 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425077 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235078
5079 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505080 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235081 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5082 EXPECT_EQ(100, response->headers->GetContentLength());
5083 }
5084
5085 // ------------------------------------------------------------------------
5086
5087 // Transaction 3: Resend a request in MyRealm's protection space --
5088 // succeed with preemptive authorization.
5089 {
[email protected]1c773ea12009-04-28 19:58:425090 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235091 request.method = "GET";
5092 request.url = GURL("http://www.google.com/x/y/z2");
5093 request.load_flags = 0;
5094
[email protected]262eec82013-03-19 21:01:365095 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505096 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275097
[email protected]f9ee6b52008-11-08 06:46:235098 MockWrite data_writes1[] = {
5099 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5100 "Host: www.google.com\r\n"
5101 "Connection: keep-alive\r\n"
5102 // The authorization for MyRealm1 gets sent preemptively
5103 // (since the url is in the same protection space)
5104 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5105 };
5106
5107 // Sever accepts the preemptive authorization
5108 MockRead data_reads1[] = {
5109 MockRead("HTTP/1.0 200 OK\r\n"),
5110 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065111 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235112 };
5113
[email protected]31a2bfe2010-02-09 08:03:395114 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5115 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075116 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235117
[email protected]49639fa2011-12-20 23:22:415118 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235119
[email protected]49639fa2011-12-20 23:22:415120 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425121 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235122
5123 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425124 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235125
[email protected]1c773ea12009-04-28 19:58:425126 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505127 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235128
5129 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5130 EXPECT_EQ(100, response->headers->GetContentLength());
5131 }
5132
5133 // ------------------------------------------------------------------------
5134
5135 // Transaction 4: request another URL in MyRealm (however the
5136 // url is not known to belong to the protection space, so no pre-auth).
5137 {
[email protected]1c773ea12009-04-28 19:58:425138 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235139 request.method = "GET";
5140 request.url = GURL("http://www.google.com/x/1");
5141 request.load_flags = 0;
5142
[email protected]262eec82013-03-19 21:01:365143 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275145
[email protected]f9ee6b52008-11-08 06:46:235146 MockWrite data_writes1[] = {
5147 MockWrite("GET /x/1 HTTP/1.1\r\n"
5148 "Host: www.google.com\r\n"
5149 "Connection: keep-alive\r\n\r\n"),
5150 };
5151
5152 MockRead data_reads1[] = {
5153 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5154 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5155 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065156 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235157 };
5158
5159 // Resend with authorization from MyRealm's cache.
5160 MockWrite data_writes2[] = {
5161 MockWrite("GET /x/1 HTTP/1.1\r\n"
5162 "Host: www.google.com\r\n"
5163 "Connection: keep-alive\r\n"
5164 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5165 };
5166
5167 // Sever accepts the authorization.
5168 MockRead data_reads2[] = {
5169 MockRead("HTTP/1.0 200 OK\r\n"),
5170 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065171 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235172 };
5173
[email protected]31a2bfe2010-02-09 08:03:395174 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5175 data_writes1, arraysize(data_writes1));
5176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5177 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075178 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5179 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235180
[email protected]49639fa2011-12-20 23:22:415181 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235182
[email protected]49639fa2011-12-20 23:22:415183 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425184 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235185
5186 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425187 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235188
[email protected]0757e7702009-03-27 04:00:225189 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415190 TestCompletionCallback callback2;
5191 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425192 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225193 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425194 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225195 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5196
[email protected]1c773ea12009-04-28 19:58:425197 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505198 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235199 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5200 EXPECT_EQ(100, response->headers->GetContentLength());
5201 }
5202
5203 // ------------------------------------------------------------------------
5204
5205 // Transaction 5: request a URL in MyRealm, but the server rejects the
5206 // cached identity. Should invalidate and re-prompt.
5207 {
[email protected]1c773ea12009-04-28 19:58:425208 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235209 request.method = "GET";
5210 request.url = GURL("http://www.google.com/p/q/t");
5211 request.load_flags = 0;
5212
[email protected]262eec82013-03-19 21:01:365213 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275215
[email protected]f9ee6b52008-11-08 06:46:235216 MockWrite data_writes1[] = {
5217 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5218 "Host: www.google.com\r\n"
5219 "Connection: keep-alive\r\n\r\n"),
5220 };
5221
5222 MockRead data_reads1[] = {
5223 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5224 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5225 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065226 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235227 };
5228
5229 // Resend with authorization from cache for MyRealm.
5230 MockWrite data_writes2[] = {
5231 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5232 "Host: www.google.com\r\n"
5233 "Connection: keep-alive\r\n"
5234 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5235 };
5236
5237 // Sever rejects the authorization.
5238 MockRead data_reads2[] = {
5239 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5240 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5241 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065242 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235243 };
5244
5245 // At this point we should prompt for new credentials for MyRealm.
5246 // Restart with username=foo3, password=foo4.
5247 MockWrite data_writes3[] = {
5248 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5249 "Host: www.google.com\r\n"
5250 "Connection: keep-alive\r\n"
5251 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5252 };
5253
5254 // Sever accepts the authorization.
5255 MockRead data_reads3[] = {
5256 MockRead("HTTP/1.0 200 OK\r\n"),
5257 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065258 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235259 };
5260
[email protected]31a2bfe2010-02-09 08:03:395261 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5262 data_writes1, arraysize(data_writes1));
5263 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5264 data_writes2, arraysize(data_writes2));
5265 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5266 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075267 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5268 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5269 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235270
[email protected]49639fa2011-12-20 23:22:415271 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235272
[email protected]49639fa2011-12-20 23:22:415273 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425274 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235275
5276 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425277 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235278
[email protected]0757e7702009-03-27 04:00:225279 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415280 TestCompletionCallback callback2;
5281 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425282 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225283 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425284 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225285 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5286
[email protected]1c773ea12009-04-28 19:58:425287 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505288 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045289 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235290
[email protected]49639fa2011-12-20 23:22:415291 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235292
[email protected]49639fa2011-12-20 23:22:415293 rv = trans->RestartWithAuth(
5294 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425295 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235296
[email protected]0757e7702009-03-27 04:00:225297 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425298 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235299
5300 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505301 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235302 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5303 EXPECT_EQ(100, response->headers->GetContentLength());
5304 }
5305}
[email protected]89ceba9a2009-03-21 03:46:065306
[email protected]3c32c5f2010-05-18 15:18:125307// Tests that nonce count increments when multiple auth attempts
5308// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025309TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445310 HttpAuthHandlerDigest::Factory* digest_factory =
5311 new HttpAuthHandlerDigest::Factory();
5312 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5313 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5314 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075315 session_deps_.http_auth_handler_factory.reset(digest_factory);
5316 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125317
5318 // Transaction 1: authenticate (foo, bar) on MyRealm1
5319 {
[email protected]3c32c5f2010-05-18 15:18:125320 HttpRequestInfo request;
5321 request.method = "GET";
5322 request.url = GURL("http://www.google.com/x/y/z");
5323 request.load_flags = 0;
5324
[email protected]262eec82013-03-19 21:01:365325 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505326 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275327
[email protected]3c32c5f2010-05-18 15:18:125328 MockWrite data_writes1[] = {
5329 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5330 "Host: www.google.com\r\n"
5331 "Connection: keep-alive\r\n\r\n"),
5332 };
5333
5334 MockRead data_reads1[] = {
5335 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5336 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5337 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065338 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125339 };
5340
5341 // Resend with authorization (username=foo, password=bar)
5342 MockWrite data_writes2[] = {
5343 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5344 "Host: www.google.com\r\n"
5345 "Connection: keep-alive\r\n"
5346 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5347 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5348 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5349 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5350 };
5351
5352 // Sever accepts the authorization.
5353 MockRead data_reads2[] = {
5354 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065355 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125356 };
5357
5358 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5359 data_writes1, arraysize(data_writes1));
5360 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5361 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075362 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5363 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125364
[email protected]49639fa2011-12-20 23:22:415365 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125366
[email protected]49639fa2011-12-20 23:22:415367 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125368 EXPECT_EQ(ERR_IO_PENDING, rv);
5369
5370 rv = callback1.WaitForResult();
5371 EXPECT_EQ(OK, rv);
5372
5373 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505374 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045375 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125376
[email protected]49639fa2011-12-20 23:22:415377 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125378
[email protected]49639fa2011-12-20 23:22:415379 rv = trans->RestartWithAuth(
5380 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125381 EXPECT_EQ(ERR_IO_PENDING, rv);
5382
5383 rv = callback2.WaitForResult();
5384 EXPECT_EQ(OK, rv);
5385
5386 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505387 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125388 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5389 }
5390
5391 // ------------------------------------------------------------------------
5392
5393 // Transaction 2: Request another resource in digestive's protection space.
5394 // This will preemptively add an Authorization header which should have an
5395 // "nc" value of 2 (as compared to 1 in the first use.
5396 {
[email protected]3c32c5f2010-05-18 15:18:125397 HttpRequestInfo request;
5398 request.method = "GET";
5399 // Note that Transaction 1 was at /x/y/z, so this is in the same
5400 // protection space as digest.
5401 request.url = GURL("http://www.google.com/x/y/a/b");
5402 request.load_flags = 0;
5403
[email protected]262eec82013-03-19 21:01:365404 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275406
[email protected]3c32c5f2010-05-18 15:18:125407 MockWrite data_writes1[] = {
5408 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5409 "Host: www.google.com\r\n"
5410 "Connection: keep-alive\r\n"
5411 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5412 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5413 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5414 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5415 };
5416
5417 // Sever accepts the authorization.
5418 MockRead data_reads1[] = {
5419 MockRead("HTTP/1.0 200 OK\r\n"),
5420 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065421 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125422 };
5423
5424 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5425 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075426 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125427
[email protected]49639fa2011-12-20 23:22:415428 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125429
[email protected]49639fa2011-12-20 23:22:415430 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125431 EXPECT_EQ(ERR_IO_PENDING, rv);
5432
5433 rv = callback1.WaitForResult();
5434 EXPECT_EQ(OK, rv);
5435
5436 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505437 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125438 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5439 }
5440}
5441
[email protected]89ceba9a2009-03-21 03:46:065442// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025443TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065444 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075445 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405446 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075447 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065448
5449 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065450 trans->read_buf_ = new IOBuffer(15);
5451 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205452 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065453
5454 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145455 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575456 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085457 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575458 response->response_time = base::Time::Now();
5459 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065460
5461 { // Setup state for response_.vary_data
5462 HttpRequestInfo request;
5463 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5464 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275465 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435466 request.extra_headers.SetHeader("Foo", "1");
5467 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505468 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065469 }
5470
5471 // Cause the above state to be reset.
5472 trans->ResetStateForRestart();
5473
5474 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075475 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065476 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205477 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575478 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5479 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045480 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085481 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575482 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065483}
5484
[email protected]bacff652009-03-31 17:50:335485// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025486TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335487 HttpRequestInfo request;
5488 request.method = "GET";
5489 request.url = GURL("https://www.google.com/");
5490 request.load_flags = 0;
5491
[email protected]3fe8d2f82013-10-17 08:56:075492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275493 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275495
[email protected]bacff652009-03-31 17:50:335496 MockWrite data_writes[] = {
5497 MockWrite("GET / HTTP/1.1\r\n"
5498 "Host: www.google.com\r\n"
5499 "Connection: keep-alive\r\n\r\n"),
5500 };
5501
5502 MockRead data_reads[] = {
5503 MockRead("HTTP/1.0 200 OK\r\n"),
5504 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5505 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065506 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335507 };
5508
[email protected]5ecc992a42009-11-11 01:41:595509 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395510 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5511 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065512 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5513 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335514
[email protected]bb88e1d32013-05-03 23:11:075515 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5516 session_deps_.socket_factory->AddSocketDataProvider(&data);
5517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335519
[email protected]49639fa2011-12-20 23:22:415520 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335521
[email protected]49639fa2011-12-20 23:22:415522 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335523 EXPECT_EQ(ERR_IO_PENDING, rv);
5524
5525 rv = callback.WaitForResult();
5526 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5527
[email protected]49639fa2011-12-20 23:22:415528 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335529 EXPECT_EQ(ERR_IO_PENDING, rv);
5530
5531 rv = callback.WaitForResult();
5532 EXPECT_EQ(OK, rv);
5533
5534 const HttpResponseInfo* response = trans->GetResponseInfo();
5535
[email protected]fe2255a2011-09-20 19:37:505536 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335537 EXPECT_EQ(100, response->headers->GetContentLength());
5538}
5539
5540// Test HTTPS connections to a site with a bad certificate, going through a
5541// proxy
[email protected]23e482282013-06-14 16:08:025542TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075543 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335544
5545 HttpRequestInfo request;
5546 request.method = "GET";
5547 request.url = GURL("https://www.google.com/");
5548 request.load_flags = 0;
5549
5550 MockWrite proxy_writes[] = {
5551 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455552 "Host: www.google.com\r\n"
5553 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335554 };
5555
5556 MockRead proxy_reads[] = {
5557 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065558 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335559 };
5560
5561 MockWrite data_writes[] = {
5562 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455563 "Host: www.google.com\r\n"
5564 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335565 MockWrite("GET / HTTP/1.1\r\n"
5566 "Host: www.google.com\r\n"
5567 "Connection: keep-alive\r\n\r\n"),
5568 };
5569
5570 MockRead data_reads[] = {
5571 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5572 MockRead("HTTP/1.0 200 OK\r\n"),
5573 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5574 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065575 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335576 };
5577
[email protected]31a2bfe2010-02-09 08:03:395578 StaticSocketDataProvider ssl_bad_certificate(
5579 proxy_reads, arraysize(proxy_reads),
5580 proxy_writes, arraysize(proxy_writes));
5581 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5582 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065583 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5584 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335585
[email protected]bb88e1d32013-05-03 23:11:075586 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5587 session_deps_.socket_factory->AddSocketDataProvider(&data);
5588 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335590
[email protected]49639fa2011-12-20 23:22:415591 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335592
5593 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075594 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335595
[email protected]3fe8d2f82013-10-17 08:56:075596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405597 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:335599
[email protected]49639fa2011-12-20 23:22:415600 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335601 EXPECT_EQ(ERR_IO_PENDING, rv);
5602
5603 rv = callback.WaitForResult();
5604 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5605
[email protected]49639fa2011-12-20 23:22:415606 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335607 EXPECT_EQ(ERR_IO_PENDING, rv);
5608
5609 rv = callback.WaitForResult();
5610 EXPECT_EQ(OK, rv);
5611
5612 const HttpResponseInfo* response = trans->GetResponseInfo();
5613
[email protected]fe2255a2011-09-20 19:37:505614 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335615 EXPECT_EQ(100, response->headers->GetContentLength());
5616 }
5617}
5618
[email protected]2df19bb2010-08-25 20:13:465619
5620// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025621TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075622 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205623 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5624 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075625 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465626
5627 HttpRequestInfo request;
5628 request.method = "GET";
5629 request.url = GURL("https://www.google.com/");
5630 request.load_flags = 0;
5631
5632 MockWrite data_writes[] = {
5633 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5634 "Host: www.google.com\r\n"
5635 "Proxy-Connection: keep-alive\r\n\r\n"),
5636 MockWrite("GET / HTTP/1.1\r\n"
5637 "Host: www.google.com\r\n"
5638 "Connection: keep-alive\r\n\r\n"),
5639 };
5640
5641 MockRead data_reads[] = {
5642 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5643 MockRead("HTTP/1.1 200 OK\r\n"),
5644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5645 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065646 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465647 };
5648
5649 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5650 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065651 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5652 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465653
[email protected]bb88e1d32013-05-03 23:11:075654 session_deps_.socket_factory->AddSocketDataProvider(&data);
5655 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5656 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465657
[email protected]49639fa2011-12-20 23:22:415658 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465659
[email protected]3fe8d2f82013-10-17 08:56:075660 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465661 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:465663
[email protected]49639fa2011-12-20 23:22:415664 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465665 EXPECT_EQ(ERR_IO_PENDING, rv);
5666
5667 rv = callback.WaitForResult();
5668 EXPECT_EQ(OK, rv);
5669 const HttpResponseInfo* response = trans->GetResponseInfo();
5670
[email protected]fe2255a2011-09-20 19:37:505671 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465672
5673 EXPECT_TRUE(response->headers->IsKeepAlive());
5674 EXPECT_EQ(200, response->headers->response_code());
5675 EXPECT_EQ(100, response->headers->GetContentLength());
5676 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205677
5678 LoadTimingInfo load_timing_info;
5679 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5680 TestLoadTimingNotReusedWithPac(load_timing_info,
5681 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465682}
5683
[email protected]511f6f52010-12-17 03:58:295684// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025685TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075686 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205687 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5688 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075689 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295690
5691 HttpRequestInfo request;
5692 request.method = "GET";
5693 request.url = GURL("https://www.google.com/");
5694 request.load_flags = 0;
5695
5696 MockWrite data_writes[] = {
5697 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5698 "Host: www.google.com\r\n"
5699 "Proxy-Connection: keep-alive\r\n\r\n"),
5700 };
5701
5702 MockRead data_reads[] = {
5703 MockRead("HTTP/1.1 302 Redirect\r\n"),
5704 MockRead("Location: http://login.example.com/\r\n"),
5705 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065706 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295707 };
5708
5709 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5710 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065711 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295712
[email protected]bb88e1d32013-05-03 23:11:075713 session_deps_.socket_factory->AddSocketDataProvider(&data);
5714 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295715
[email protected]49639fa2011-12-20 23:22:415716 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295717
[email protected]3fe8d2f82013-10-17 08:56:075718 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295719 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075720 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295721
[email protected]49639fa2011-12-20 23:22:415722 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295723 EXPECT_EQ(ERR_IO_PENDING, rv);
5724
5725 rv = callback.WaitForResult();
5726 EXPECT_EQ(OK, rv);
5727 const HttpResponseInfo* response = trans->GetResponseInfo();
5728
[email protected]fe2255a2011-09-20 19:37:505729 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295730
5731 EXPECT_EQ(302, response->headers->response_code());
5732 std::string url;
5733 EXPECT_TRUE(response->headers->IsRedirect(&url));
5734 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205735
5736 // In the case of redirects from proxies, HttpNetworkTransaction returns
5737 // timing for the proxy connection instead of the connection to the host,
5738 // and no send / receive times.
5739 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5740 LoadTimingInfo load_timing_info;
5741 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5742
5743 EXPECT_FALSE(load_timing_info.socket_reused);
5744 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5745
5746 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5747 EXPECT_LE(load_timing_info.proxy_resolve_start,
5748 load_timing_info.proxy_resolve_end);
5749 EXPECT_LE(load_timing_info.proxy_resolve_end,
5750 load_timing_info.connect_timing.connect_start);
5751 ExpectConnectTimingHasTimes(
5752 load_timing_info.connect_timing,
5753 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5754
5755 EXPECT_TRUE(load_timing_info.send_start.is_null());
5756 EXPECT_TRUE(load_timing_info.send_end.is_null());
5757 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:295758}
5759
5760// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025761TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075762 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295763 ProxyService::CreateFixed("https://proxy:70"));
5764
5765 HttpRequestInfo request;
5766 request.method = "GET";
5767 request.url = GURL("https://www.google.com/");
5768 request.load_flags = 0;
5769
[email protected]9075f51c2013-08-15 17:53:545770 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5771 LOWEST));
[email protected]c10b20852013-05-15 21:29:205772 scoped_ptr<SpdyFrame> goaway(
5773 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295774 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065775 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:125776 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295777 };
5778
5779 static const char* const kExtraHeaders[] = {
5780 "location",
5781 "http://login.example.com/",
5782 };
[email protected]ff98d7f02012-03-22 21:44:195783 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025784 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295785 arraysize(kExtraHeaders)/2, 1));
5786 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065787 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5788 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:295789 };
5790
[email protected]dd54bd82012-07-19 23:44:575791 DelayedSocketData data(
5792 1, // wait for one write to finish before reading.
5793 data_reads, arraysize(data_reads),
5794 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065795 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025796 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295797
[email protected]bb88e1d32013-05-03 23:11:075798 session_deps_.socket_factory->AddSocketDataProvider(&data);
5799 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295800
[email protected]49639fa2011-12-20 23:22:415801 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295802
[email protected]3fe8d2f82013-10-17 08:56:075803 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295804 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295806
[email protected]49639fa2011-12-20 23:22:415807 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295808 EXPECT_EQ(ERR_IO_PENDING, rv);
5809
5810 rv = callback.WaitForResult();
5811 EXPECT_EQ(OK, rv);
5812 const HttpResponseInfo* response = trans->GetResponseInfo();
5813
[email protected]fe2255a2011-09-20 19:37:505814 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295815
5816 EXPECT_EQ(302, response->headers->response_code());
5817 std::string url;
5818 EXPECT_TRUE(response->headers->IsRedirect(&url));
5819 EXPECT_EQ("http://login.example.com/", url);
5820}
5821
[email protected]4eddbc732012-08-09 05:40:175822// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025823TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175824 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075825 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295826 ProxyService::CreateFixed("https://proxy:70"));
5827
5828 HttpRequestInfo request;
5829 request.method = "GET";
5830 request.url = GURL("https://www.google.com/");
5831 request.load_flags = 0;
5832
5833 MockWrite data_writes[] = {
5834 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5835 "Host: www.google.com\r\n"
5836 "Proxy-Connection: keep-alive\r\n\r\n"),
5837 };
5838
5839 MockRead data_reads[] = {
5840 MockRead("HTTP/1.1 404 Not Found\r\n"),
5841 MockRead("Content-Length: 23\r\n\r\n"),
5842 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:065843 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295844 };
5845
5846 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5847 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065848 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295849
[email protected]bb88e1d32013-05-03 23:11:075850 session_deps_.socket_factory->AddSocketDataProvider(&data);
5851 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295852
[email protected]49639fa2011-12-20 23:22:415853 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295854
[email protected]3fe8d2f82013-10-17 08:56:075855 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295856 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075857 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295858
[email protected]49639fa2011-12-20 23:22:415859 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295860 EXPECT_EQ(ERR_IO_PENDING, rv);
5861
5862 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175863 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295864
[email protected]4eddbc732012-08-09 05:40:175865 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295866}
5867
[email protected]4eddbc732012-08-09 05:40:175868// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025869TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175870 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075871 session_deps_.proxy_service.reset(
5872 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:295873
5874 HttpRequestInfo request;
5875 request.method = "GET";
5876 request.url = GURL("https://www.google.com/");
5877 request.load_flags = 0;
5878
[email protected]9075f51c2013-08-15 17:53:545879 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5880 LOWEST));
[email protected]c10b20852013-05-15 21:29:205881 scoped_ptr<SpdyFrame> rst(
5882 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295883 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065884 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175885 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295886 };
5887
5888 static const char* const kExtraHeaders[] = {
5889 "location",
5890 "http://login.example.com/",
5891 };
[email protected]ff98d7f02012-03-22 21:44:195892 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025893 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295894 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:195895 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:025896 spdy_util_.ConstructSpdyBodyFrame(
5897 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:295898 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065899 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5900 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175901 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:295902 };
5903
[email protected]dd54bd82012-07-19 23:44:575904 DelayedSocketData data(
5905 1, // wait for one write to finish before reading.
5906 data_reads, arraysize(data_reads),
5907 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065908 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025909 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295910
[email protected]bb88e1d32013-05-03 23:11:075911 session_deps_.socket_factory->AddSocketDataProvider(&data);
5912 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295913
[email protected]49639fa2011-12-20 23:22:415914 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295915
[email protected]3fe8d2f82013-10-17 08:56:075916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295917 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295919
[email protected]49639fa2011-12-20 23:22:415920 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295921 EXPECT_EQ(ERR_IO_PENDING, rv);
5922
5923 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175924 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295925
[email protected]4eddbc732012-08-09 05:40:175926 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295927}
5928
[email protected]0c5fb722012-02-28 11:50:355929// Test the request-challenge-retry sequence for basic auth, through
5930// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:025931TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:355932 HttpRequestInfo request;
5933 request.method = "GET";
5934 request.url = GURL("https://www.google.com/");
5935 // when the no authentication data flag is set.
5936 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
5937
5938 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075939 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205940 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:295941 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075942 session_deps_.net_log = log.bound().net_log();
5943 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:355944
5945 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:545946 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5947 LOWEST));
[email protected]c10b20852013-05-15 21:29:205948 scoped_ptr<SpdyFrame> rst(
5949 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:355950
5951 // After calling trans->RestartWithAuth(), this is the request we should
5952 // be issuing -- the final header line contains the credentials.
5953 const char* const kAuthCredentials[] = {
5954 "proxy-authorization", "Basic Zm9vOmJhcg==",
5955 };
[email protected]fba2dbde2013-05-24 16:09:015956 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:545957 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:355958 // fetch https://www.google.com/ via HTTP
5959 const char get[] = "GET / HTTP/1.1\r\n"
5960 "Host: www.google.com\r\n"
5961 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:195962 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:025963 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:355964
5965 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:205966 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:215967 CreateMockWrite(*rst, 4, ASYNC),
5968 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:205969 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:355970 };
5971
5972 // The proxy responds to the connect with a 407, using a persistent
5973 // connection.
5974 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:025975 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
5976 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:355977 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
5978 };
5979
[email protected]ff98d7f02012-03-22 21:44:195980 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:235981 spdy_util_.ConstructSpdyControlFrame(NULL,
5982 0,
5983 false,
5984 1,
5985 LOWEST,
5986 SYN_REPLY,
5987 CONTROL_FLAG_NONE,
5988 kAuthChallenge,
5989 arraysize(kAuthChallenge),
5990 0));
[email protected]0c5fb722012-02-28 11:50:355991
[email protected]23e482282013-06-14 16:08:025992 scoped_ptr<SpdyFrame> conn_resp(
5993 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:355994 const char resp[] = "HTTP/1.1 200 OK\r\n"
5995 "Content-Length: 5\r\n\r\n";
5996
[email protected]ff98d7f02012-03-22 21:44:195997 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025998 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:195999 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026000 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356001 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206002 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6003 CreateMockRead(*conn_resp, 6, ASYNC),
6004 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6005 CreateMockRead(*wrapped_body, 10, ASYNC),
6006 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356007 };
6008
[email protected]dd54bd82012-07-19 23:44:576009 OrderedSocketData spdy_data(
6010 spdy_reads, arraysize(spdy_reads),
6011 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076012 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356013 // Negotiate SPDY to the proxy
6014 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026015 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076016 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356017 // Vanilla SSL to the server
6018 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076019 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356020
6021 TestCompletionCallback callback1;
6022
[email protected]262eec82013-03-19 21:01:366023 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506024 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356025
6026 int rv = trans->Start(&request, callback1.callback(), log.bound());
6027 EXPECT_EQ(ERR_IO_PENDING, rv);
6028
6029 rv = callback1.WaitForResult();
6030 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576031 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356032 log.GetEntries(&entries);
6033 size_t pos = ExpectLogContainsSomewhere(
6034 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6035 NetLog::PHASE_NONE);
6036 ExpectLogContainsSomewhere(
6037 entries, pos,
6038 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6039 NetLog::PHASE_NONE);
6040
6041 const HttpResponseInfo* response = trans->GetResponseInfo();
6042 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506043 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356044 EXPECT_EQ(407, response->headers->response_code());
6045 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6046 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6047 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6048
6049 TestCompletionCallback callback2;
6050
6051 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6052 callback2.callback());
6053 EXPECT_EQ(ERR_IO_PENDING, rv);
6054
6055 rv = callback2.WaitForResult();
6056 EXPECT_EQ(OK, rv);
6057
6058 response = trans->GetResponseInfo();
6059 ASSERT_TRUE(response != NULL);
6060
6061 EXPECT_TRUE(response->headers->IsKeepAlive());
6062 EXPECT_EQ(200, response->headers->response_code());
6063 EXPECT_EQ(5, response->headers->GetContentLength());
6064 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6065
6066 // The password prompt info should not be set.
6067 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6068
[email protected]029c83b62013-01-24 05:28:206069 LoadTimingInfo load_timing_info;
6070 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6071 TestLoadTimingNotReusedWithPac(load_timing_info,
6072 CONNECT_TIMING_HAS_SSL_TIMES);
6073
[email protected]0c5fb722012-02-28 11:50:356074 trans.reset();
6075 session->CloseAllConnections();
6076}
6077
[email protected]7c6f7ba2012-04-03 04:09:296078// Test that an explicitly trusted SPDY proxy can push a resource from an
6079// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026080TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296081 HttpRequestInfo request;
6082 HttpRequestInfo push_request;
6083
[email protected]7c6f7ba2012-04-03 04:09:296084 request.method = "GET";
6085 request.url = GURL("http://www.google.com/");
6086 push_request.method = "GET";
6087 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6088
[email protected]7c6f7ba2012-04-03 04:09:296089 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076090 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206091 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296092 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076093 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506094
6095 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076096 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506097
[email protected]bb88e1d32013-05-03 23:11:076098 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296099
[email protected]cdf8f7e72013-05-23 10:56:466100 scoped_ptr<SpdyFrame> stream1_syn(
6101 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296102
6103 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466104 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296105 };
6106
6107 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026108 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296109
6110 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026111 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296112
6113 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026114 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296115 0,
6116 2,
6117 1,
6118 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436119 const char kPushedData[] = "pushed";
6120 scoped_ptr<SpdyFrame> stream2_body(
6121 spdy_util_.ConstructSpdyBodyFrame(
6122 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296123
6124 MockRead spdy_reads[] = {
6125 CreateMockRead(*stream1_reply, 2, ASYNC),
6126 CreateMockRead(*stream2_syn, 3, ASYNC),
6127 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436128 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296129 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6130 };
6131
[email protected]dd54bd82012-07-19 23:44:576132 OrderedSocketData spdy_data(
6133 spdy_reads, arraysize(spdy_reads),
6134 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076135 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296136 // Negotiate SPDY to the proxy
6137 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026138 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076139 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296140
[email protected]262eec82013-03-19 21:01:366141 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506142 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296143 TestCompletionCallback callback;
6144 int rv = trans->Start(&request, callback.callback(), log.bound());
6145 EXPECT_EQ(ERR_IO_PENDING, rv);
6146
6147 rv = callback.WaitForResult();
6148 EXPECT_EQ(OK, rv);
6149 const HttpResponseInfo* response = trans->GetResponseInfo();
6150
[email protected]262eec82013-03-19 21:01:366151 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6153 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296154 EXPECT_EQ(ERR_IO_PENDING, rv);
6155
6156 rv = callback.WaitForResult();
6157 EXPECT_EQ(OK, rv);
6158 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6159
6160 ASSERT_TRUE(response != NULL);
6161 EXPECT_TRUE(response->headers->IsKeepAlive());
6162
6163 EXPECT_EQ(200, response->headers->response_code());
6164 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6165
6166 std::string response_data;
6167 rv = ReadTransaction(trans.get(), &response_data);
6168 EXPECT_EQ(OK, rv);
6169 EXPECT_EQ("hello!", response_data);
6170
[email protected]029c83b62013-01-24 05:28:206171 LoadTimingInfo load_timing_info;
6172 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6173 TestLoadTimingNotReusedWithPac(load_timing_info,
6174 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6175
[email protected]7c6f7ba2012-04-03 04:09:296176 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506177 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296178 EXPECT_EQ(200, push_response->headers->response_code());
6179
6180 rv = ReadTransaction(push_trans.get(), &response_data);
6181 EXPECT_EQ(OK, rv);
6182 EXPECT_EQ("pushed", response_data);
6183
[email protected]029c83b62013-01-24 05:28:206184 LoadTimingInfo push_load_timing_info;
6185 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6186 TestLoadTimingReusedWithPac(push_load_timing_info);
6187 // The transactions should share a socket ID, despite being for different
6188 // origins.
6189 EXPECT_EQ(load_timing_info.socket_log_id,
6190 push_load_timing_info.socket_log_id);
6191
[email protected]7c6f7ba2012-04-03 04:09:296192 trans.reset();
6193 push_trans.reset();
6194 session->CloseAllConnections();
6195}
6196
[email protected]8c843192012-04-05 07:15:006197// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026198TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006199 HttpRequestInfo request;
6200
6201 request.method = "GET";
6202 request.url = GURL("http://www.google.com/");
6203
[email protected]8c843192012-04-05 07:15:006204 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076205 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006206 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296207 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076208 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506209
6210 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076211 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506212
[email protected]bb88e1d32013-05-03 23:11:076213 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006214
[email protected]cdf8f7e72013-05-23 10:56:466215 scoped_ptr<SpdyFrame> stream1_syn(
6216 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006217
6218 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206219 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006220
6221 MockWrite spdy_writes[] = {
6222 CreateMockWrite(*stream1_syn, 1, ASYNC),
6223 CreateMockWrite(*push_rst, 4),
6224 };
6225
6226 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026227 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006228
6229 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026230 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006231
6232 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026233 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006234 0,
6235 2,
6236 1,
6237 "https://www.another-origin.com/foo.dat"));
6238
6239 MockRead spdy_reads[] = {
6240 CreateMockRead(*stream1_reply, 2, ASYNC),
6241 CreateMockRead(*stream2_syn, 3, ASYNC),
6242 CreateMockRead(*stream1_body, 5, ASYNC),
6243 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6244 };
6245
[email protected]dd54bd82012-07-19 23:44:576246 OrderedSocketData spdy_data(
6247 spdy_reads, arraysize(spdy_reads),
6248 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076249 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006250 // Negotiate SPDY to the proxy
6251 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026252 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076253 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006254
[email protected]262eec82013-03-19 21:01:366255 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006257 TestCompletionCallback callback;
6258 int rv = trans->Start(&request, callback.callback(), log.bound());
6259 EXPECT_EQ(ERR_IO_PENDING, rv);
6260
6261 rv = callback.WaitForResult();
6262 EXPECT_EQ(OK, rv);
6263 const HttpResponseInfo* response = trans->GetResponseInfo();
6264
6265 ASSERT_TRUE(response != NULL);
6266 EXPECT_TRUE(response->headers->IsKeepAlive());
6267
6268 EXPECT_EQ(200, response->headers->response_code());
6269 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6270
6271 std::string response_data;
6272 rv = ReadTransaction(trans.get(), &response_data);
6273 EXPECT_EQ(OK, rv);
6274 EXPECT_EQ("hello!", response_data);
6275
6276 trans.reset();
6277 session->CloseAllConnections();
6278}
6279
[email protected]2df19bb2010-08-25 20:13:466280// Test HTTPS connections to a site with a bad certificate, going through an
6281// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026282TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076283 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116284 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466285
6286 HttpRequestInfo request;
6287 request.method = "GET";
6288 request.url = GURL("https://www.google.com/");
6289 request.load_flags = 0;
6290
6291 // Attempt to fetch the URL from a server with a bad cert
6292 MockWrite bad_cert_writes[] = {
6293 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6294 "Host: www.google.com\r\n"
6295 "Proxy-Connection: keep-alive\r\n\r\n"),
6296 };
6297
6298 MockRead bad_cert_reads[] = {
6299 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066300 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466301 };
6302
6303 // Attempt to fetch the URL with a good cert
6304 MockWrite good_data_writes[] = {
6305 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6306 "Host: www.google.com\r\n"
6307 "Proxy-Connection: keep-alive\r\n\r\n"),
6308 MockWrite("GET / HTTP/1.1\r\n"
6309 "Host: www.google.com\r\n"
6310 "Connection: keep-alive\r\n\r\n"),
6311 };
6312
6313 MockRead good_cert_reads[] = {
6314 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6315 MockRead("HTTP/1.0 200 OK\r\n"),
6316 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6317 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066318 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466319 };
6320
6321 StaticSocketDataProvider ssl_bad_certificate(
6322 bad_cert_reads, arraysize(bad_cert_reads),
6323 bad_cert_writes, arraysize(bad_cert_writes));
6324 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6325 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066326 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6327 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466328
6329 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6331 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466333
6334 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6336 session_deps_.socket_factory->AddSocketDataProvider(&data);
6337 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466338
[email protected]49639fa2011-12-20 23:22:416339 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466340
[email protected]3fe8d2f82013-10-17 08:56:076341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466342 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076343 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466344
[email protected]49639fa2011-12-20 23:22:416345 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466346 EXPECT_EQ(ERR_IO_PENDING, rv);
6347
6348 rv = callback.WaitForResult();
6349 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6350
[email protected]49639fa2011-12-20 23:22:416351 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466352 EXPECT_EQ(ERR_IO_PENDING, rv);
6353
6354 rv = callback.WaitForResult();
6355 EXPECT_EQ(OK, rv);
6356
6357 const HttpResponseInfo* response = trans->GetResponseInfo();
6358
[email protected]fe2255a2011-09-20 19:37:506359 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466360 EXPECT_EQ(100, response->headers->GetContentLength());
6361}
6362
[email protected]23e482282013-06-14 16:08:026363TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426364 HttpRequestInfo request;
6365 request.method = "GET";
6366 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436367 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6368 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426369
[email protected]3fe8d2f82013-10-17 08:56:076370 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276371 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076372 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276373
[email protected]1c773ea12009-04-28 19:58:426374 MockWrite data_writes[] = {
6375 MockWrite("GET / HTTP/1.1\r\n"
6376 "Host: www.google.com\r\n"
6377 "Connection: keep-alive\r\n"
6378 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6379 };
6380
6381 // Lastly, the server responds with the actual content.
6382 MockRead data_reads[] = {
6383 MockRead("HTTP/1.0 200 OK\r\n"),
6384 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6385 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066386 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426387 };
6388
[email protected]31a2bfe2010-02-09 08:03:396389 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6390 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076391 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426392
[email protected]49639fa2011-12-20 23:22:416393 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426394
[email protected]49639fa2011-12-20 23:22:416395 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426396 EXPECT_EQ(ERR_IO_PENDING, rv);
6397
6398 rv = callback.WaitForResult();
6399 EXPECT_EQ(OK, rv);
6400}
6401
[email protected]23e482282013-06-14 16:08:026402TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296403 HttpRequestInfo request;
6404 request.method = "GET";
6405 request.url = GURL("https://www.google.com/");
6406 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6407 "Chromium Ultra Awesome X Edition");
6408
[email protected]bb88e1d32013-05-03 23:11:076409 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076410 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276411 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276413
[email protected]da81f132010-08-18 23:39:296414 MockWrite data_writes[] = {
6415 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6416 "Host: www.google.com\r\n"
6417 "Proxy-Connection: keep-alive\r\n"
6418 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6419 };
6420 MockRead data_reads[] = {
6421 // Return an error, so the transaction stops here (this test isn't
6422 // interested in the rest).
6423 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6424 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6425 MockRead("Proxy-Connection: close\r\n\r\n"),
6426 };
6427
6428 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6429 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076430 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296431
[email protected]49639fa2011-12-20 23:22:416432 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296433
[email protected]49639fa2011-12-20 23:22:416434 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296435 EXPECT_EQ(ERR_IO_PENDING, rv);
6436
6437 rv = callback.WaitForResult();
6438 EXPECT_EQ(OK, rv);
6439}
6440
[email protected]23e482282013-06-14 16:08:026441TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426442 HttpRequestInfo request;
6443 request.method = "GET";
6444 request.url = GURL("http://www.google.com/");
6445 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166446 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6447 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426448
[email protected]3fe8d2f82013-10-17 08:56:076449 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276450 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076451 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276452
[email protected]1c773ea12009-04-28 19:58:426453 MockWrite data_writes[] = {
6454 MockWrite("GET / HTTP/1.1\r\n"
6455 "Host: www.google.com\r\n"
6456 "Connection: keep-alive\r\n"
6457 "Referer: http://the.previous.site.com/\r\n\r\n"),
6458 };
6459
6460 // Lastly, the server responds with the actual content.
6461 MockRead data_reads[] = {
6462 MockRead("HTTP/1.0 200 OK\r\n"),
6463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6464 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066465 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426466 };
6467
[email protected]31a2bfe2010-02-09 08:03:396468 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6469 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076470 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426471
[email protected]49639fa2011-12-20 23:22:416472 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426473
[email protected]49639fa2011-12-20 23:22:416474 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426475 EXPECT_EQ(ERR_IO_PENDING, rv);
6476
6477 rv = callback.WaitForResult();
6478 EXPECT_EQ(OK, rv);
6479}
6480
[email protected]23e482282013-06-14 16:08:026481TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426482 HttpRequestInfo request;
6483 request.method = "POST";
6484 request.url = GURL("http://www.google.com/");
6485
[email protected]3fe8d2f82013-10-17 08:56:076486 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276487 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076488 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276489
[email protected]1c773ea12009-04-28 19:58:426490 MockWrite data_writes[] = {
6491 MockWrite("POST / HTTP/1.1\r\n"
6492 "Host: www.google.com\r\n"
6493 "Connection: keep-alive\r\n"
6494 "Content-Length: 0\r\n\r\n"),
6495 };
6496
6497 // Lastly, the server responds with the actual content.
6498 MockRead data_reads[] = {
6499 MockRead("HTTP/1.0 200 OK\r\n"),
6500 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6501 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066502 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426503 };
6504
[email protected]31a2bfe2010-02-09 08:03:396505 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6506 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076507 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426508
[email protected]49639fa2011-12-20 23:22:416509 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426510
[email protected]49639fa2011-12-20 23:22:416511 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426512 EXPECT_EQ(ERR_IO_PENDING, rv);
6513
6514 rv = callback.WaitForResult();
6515 EXPECT_EQ(OK, rv);
6516}
6517
[email protected]23e482282013-06-14 16:08:026518TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426519 HttpRequestInfo request;
6520 request.method = "PUT";
6521 request.url = GURL("http://www.google.com/");
6522
[email protected]3fe8d2f82013-10-17 08:56:076523 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276524 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076525 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276526
[email protected]1c773ea12009-04-28 19:58:426527 MockWrite data_writes[] = {
6528 MockWrite("PUT / HTTP/1.1\r\n"
6529 "Host: www.google.com\r\n"
6530 "Connection: keep-alive\r\n"
6531 "Content-Length: 0\r\n\r\n"),
6532 };
6533
6534 // Lastly, the server responds with the actual content.
6535 MockRead data_reads[] = {
6536 MockRead("HTTP/1.0 200 OK\r\n"),
6537 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6538 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066539 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426540 };
6541
[email protected]31a2bfe2010-02-09 08:03:396542 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6543 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076544 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426545
[email protected]49639fa2011-12-20 23:22:416546 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426547
[email protected]49639fa2011-12-20 23:22:416548 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426549 EXPECT_EQ(ERR_IO_PENDING, rv);
6550
6551 rv = callback.WaitForResult();
6552 EXPECT_EQ(OK, rv);
6553}
6554
[email protected]23e482282013-06-14 16:08:026555TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426556 HttpRequestInfo request;
6557 request.method = "HEAD";
6558 request.url = GURL("http://www.google.com/");
6559
[email protected]3fe8d2f82013-10-17 08:56:076560 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276561 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076562 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276563
[email protected]1c773ea12009-04-28 19:58:426564 MockWrite data_writes[] = {
6565 MockWrite("HEAD / HTTP/1.1\r\n"
6566 "Host: www.google.com\r\n"
6567 "Connection: keep-alive\r\n"
6568 "Content-Length: 0\r\n\r\n"),
6569 };
6570
6571 // Lastly, the server responds with the actual content.
6572 MockRead data_reads[] = {
6573 MockRead("HTTP/1.0 200 OK\r\n"),
6574 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6575 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066576 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426577 };
6578
[email protected]31a2bfe2010-02-09 08:03:396579 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6580 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076581 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426582
[email protected]49639fa2011-12-20 23:22:416583 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426584
[email protected]49639fa2011-12-20 23:22:416585 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426586 EXPECT_EQ(ERR_IO_PENDING, rv);
6587
6588 rv = callback.WaitForResult();
6589 EXPECT_EQ(OK, rv);
6590}
6591
[email protected]23e482282013-06-14 16:08:026592TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426593 HttpRequestInfo request;
6594 request.method = "GET";
6595 request.url = GURL("http://www.google.com/");
6596 request.load_flags = LOAD_BYPASS_CACHE;
6597
[email protected]3fe8d2f82013-10-17 08:56:076598 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276599 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276601
[email protected]1c773ea12009-04-28 19:58:426602 MockWrite data_writes[] = {
6603 MockWrite("GET / HTTP/1.1\r\n"
6604 "Host: www.google.com\r\n"
6605 "Connection: keep-alive\r\n"
6606 "Pragma: no-cache\r\n"
6607 "Cache-Control: no-cache\r\n\r\n"),
6608 };
6609
6610 // Lastly, the server responds with the actual content.
6611 MockRead data_reads[] = {
6612 MockRead("HTTP/1.0 200 OK\r\n"),
6613 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6614 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066615 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426616 };
6617
[email protected]31a2bfe2010-02-09 08:03:396618 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6619 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076620 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426621
[email protected]49639fa2011-12-20 23:22:416622 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426623
[email protected]49639fa2011-12-20 23:22:416624 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426625 EXPECT_EQ(ERR_IO_PENDING, rv);
6626
6627 rv = callback.WaitForResult();
6628 EXPECT_EQ(OK, rv);
6629}
6630
[email protected]23e482282013-06-14 16:08:026631TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426632 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426633 HttpRequestInfo request;
6634 request.method = "GET";
6635 request.url = GURL("http://www.google.com/");
6636 request.load_flags = LOAD_VALIDATE_CACHE;
6637
[email protected]3fe8d2f82013-10-17 08:56:076638 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276639 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276641
[email protected]1c773ea12009-04-28 19:58:426642 MockWrite data_writes[] = {
6643 MockWrite("GET / HTTP/1.1\r\n"
6644 "Host: www.google.com\r\n"
6645 "Connection: keep-alive\r\n"
6646 "Cache-Control: max-age=0\r\n\r\n"),
6647 };
6648
6649 // Lastly, the server responds with the actual content.
6650 MockRead data_reads[] = {
6651 MockRead("HTTP/1.0 200 OK\r\n"),
6652 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6653 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066654 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426655 };
6656
[email protected]31a2bfe2010-02-09 08:03:396657 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6658 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076659 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426660
[email protected]49639fa2011-12-20 23:22:416661 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426662
[email protected]49639fa2011-12-20 23:22:416663 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426664 EXPECT_EQ(ERR_IO_PENDING, rv);
6665
6666 rv = callback.WaitForResult();
6667 EXPECT_EQ(OK, rv);
6668}
6669
[email protected]23e482282013-06-14 16:08:026670TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426671 HttpRequestInfo request;
6672 request.method = "GET";
6673 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436674 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426675
[email protected]3fe8d2f82013-10-17 08:56:076676 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276677 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076678 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276679
[email protected]1c773ea12009-04-28 19:58:426680 MockWrite data_writes[] = {
6681 MockWrite("GET / HTTP/1.1\r\n"
6682 "Host: www.google.com\r\n"
6683 "Connection: keep-alive\r\n"
6684 "FooHeader: Bar\r\n\r\n"),
6685 };
6686
6687 // Lastly, the server responds with the actual content.
6688 MockRead data_reads[] = {
6689 MockRead("HTTP/1.0 200 OK\r\n"),
6690 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6691 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066692 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426693 };
6694
[email protected]31a2bfe2010-02-09 08:03:396695 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6696 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076697 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426698
[email protected]49639fa2011-12-20 23:22:416699 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426700
[email protected]49639fa2011-12-20 23:22:416701 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426702 EXPECT_EQ(ERR_IO_PENDING, rv);
6703
6704 rv = callback.WaitForResult();
6705 EXPECT_EQ(OK, rv);
6706}
6707
[email protected]23e482282013-06-14 16:08:026708TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476709 HttpRequestInfo request;
6710 request.method = "GET";
6711 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436712 request.extra_headers.SetHeader("referer", "www.foo.com");
6713 request.extra_headers.SetHeader("hEllo", "Kitty");
6714 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476715
[email protected]3fe8d2f82013-10-17 08:56:076716 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276717 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076718 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276719
[email protected]270c6412010-03-29 22:02:476720 MockWrite data_writes[] = {
6721 MockWrite("GET / HTTP/1.1\r\n"
6722 "Host: www.google.com\r\n"
6723 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166724 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476725 "hEllo: Kitty\r\n"
6726 "FoO: bar\r\n\r\n"),
6727 };
6728
6729 // Lastly, the server responds with the actual content.
6730 MockRead data_reads[] = {
6731 MockRead("HTTP/1.0 200 OK\r\n"),
6732 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6733 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066734 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476735 };
6736
6737 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6738 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076739 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:476740
[email protected]49639fa2011-12-20 23:22:416741 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:476742
[email protected]49639fa2011-12-20 23:22:416743 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:476744 EXPECT_EQ(ERR_IO_PENDING, rv);
6745
6746 rv = callback.WaitForResult();
6747 EXPECT_EQ(OK, rv);
6748}
6749
[email protected]23e482282013-06-14 16:08:026750TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276751 HttpRequestInfo request;
6752 request.method = "GET";
6753 request.url = GURL("http://www.google.com/");
6754 request.load_flags = 0;
6755
[email protected]bb88e1d32013-05-03 23:11:076756 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206757 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6758 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076759 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026760
[email protected]3fe8d2f82013-10-17 08:56:076761 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:026762 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076763 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:026764
[email protected]3cd17242009-06-23 02:59:026765 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6766 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6767
6768 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066769 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026770 MockWrite("GET / HTTP/1.1\r\n"
6771 "Host: www.google.com\r\n"
6772 "Connection: keep-alive\r\n\r\n")
6773 };
6774
6775 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066776 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:026777 MockRead("HTTP/1.0 200 OK\r\n"),
6778 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6779 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066780 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026781 };
6782
[email protected]31a2bfe2010-02-09 08:03:396783 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6784 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076785 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026786
[email protected]49639fa2011-12-20 23:22:416787 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026788
[email protected]49639fa2011-12-20 23:22:416789 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026790 EXPECT_EQ(ERR_IO_PENDING, rv);
6791
6792 rv = callback.WaitForResult();
6793 EXPECT_EQ(OK, rv);
6794
6795 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506796 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026797
[email protected]029c83b62013-01-24 05:28:206798 LoadTimingInfo load_timing_info;
6799 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6800 TestLoadTimingNotReusedWithPac(load_timing_info,
6801 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6802
[email protected]3cd17242009-06-23 02:59:026803 std::string response_text;
6804 rv = ReadTransaction(trans.get(), &response_text);
6805 EXPECT_EQ(OK, rv);
6806 EXPECT_EQ("Payload", response_text);
6807}
6808
[email protected]23e482282013-06-14 16:08:026809TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276810 HttpRequestInfo request;
6811 request.method = "GET";
6812 request.url = GURL("https://www.google.com/");
6813 request.load_flags = 0;
6814
[email protected]bb88e1d32013-05-03 23:11:076815 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206816 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6817 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076818 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026819
[email protected]3fe8d2f82013-10-17 08:56:076820 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:026821 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076822 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:026823
[email protected]3cd17242009-06-23 02:59:026824 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6825 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6826
6827 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066828 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:356829 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026830 MockWrite("GET / HTTP/1.1\r\n"
6831 "Host: www.google.com\r\n"
6832 "Connection: keep-alive\r\n\r\n")
6833 };
6834
6835 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016836 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6837 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:356838 MockRead("HTTP/1.0 200 OK\r\n"),
6839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6840 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066841 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356842 };
6843
[email protected]31a2bfe2010-02-09 08:03:396844 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6845 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076846 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356847
[email protected]8ddf8322012-02-23 18:08:066848 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:356850
[email protected]49639fa2011-12-20 23:22:416851 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356852
[email protected]49639fa2011-12-20 23:22:416853 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356854 EXPECT_EQ(ERR_IO_PENDING, rv);
6855
6856 rv = callback.WaitForResult();
6857 EXPECT_EQ(OK, rv);
6858
[email protected]029c83b62013-01-24 05:28:206859 LoadTimingInfo load_timing_info;
6860 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6861 TestLoadTimingNotReusedWithPac(load_timing_info,
6862 CONNECT_TIMING_HAS_SSL_TIMES);
6863
[email protected]e0c27be2009-07-15 13:09:356864 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506865 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356866
6867 std::string response_text;
6868 rv = ReadTransaction(trans.get(), &response_text);
6869 EXPECT_EQ(OK, rv);
6870 EXPECT_EQ("Payload", response_text);
6871}
6872
[email protected]23e482282013-06-14 16:08:026873TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:206874 HttpRequestInfo request;
6875 request.method = "GET";
6876 request.url = GURL("http://www.google.com/");
6877 request.load_flags = 0;
6878
[email protected]bb88e1d32013-05-03 23:11:076879 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206880 ProxyService::CreateFixed("socks4://myproxy:1080"));
6881 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076882 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:206883
[email protected]3fe8d2f82013-10-17 08:56:076884 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:206885 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:206887
6888 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6889 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6890
6891 MockWrite data_writes[] = {
6892 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6893 MockWrite("GET / HTTP/1.1\r\n"
6894 "Host: www.google.com\r\n"
6895 "Connection: keep-alive\r\n\r\n")
6896 };
6897
6898 MockRead data_reads[] = {
6899 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6900 MockRead("HTTP/1.0 200 OK\r\n"),
6901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6902 MockRead("Payload"),
6903 MockRead(SYNCHRONOUS, OK)
6904 };
6905
6906 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6907 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076908 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:206909
6910 TestCompletionCallback callback;
6911
6912 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6913 EXPECT_EQ(ERR_IO_PENDING, rv);
6914
6915 rv = callback.WaitForResult();
6916 EXPECT_EQ(OK, rv);
6917
6918 const HttpResponseInfo* response = trans->GetResponseInfo();
6919 ASSERT_TRUE(response != NULL);
6920
6921 LoadTimingInfo load_timing_info;
6922 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6923 TestLoadTimingNotReused(load_timing_info,
6924 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6925
6926 std::string response_text;
6927 rv = ReadTransaction(trans.get(), &response_text);
6928 EXPECT_EQ(OK, rv);
6929 EXPECT_EQ("Payload", response_text);
6930}
6931
[email protected]23e482282013-06-14 16:08:026932TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276933 HttpRequestInfo request;
6934 request.method = "GET";
6935 request.url = GURL("http://www.google.com/");
6936 request.load_flags = 0;
6937
[email protected]bb88e1d32013-05-03 23:11:076938 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206939 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6940 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076941 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356942
[email protected]3fe8d2f82013-10-17 08:56:076943 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:356944 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076945 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:356946
[email protected]e0c27be2009-07-15 13:09:356947 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6948 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376949 const char kSOCKS5OkRequest[] = {
6950 0x05, // Version
6951 0x01, // Command (CONNECT)
6952 0x00, // Reserved.
6953 0x03, // Address type (DOMAINNAME).
6954 0x0E, // Length of domain (14)
6955 // Domain string:
6956 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6957 0x00, 0x50, // 16-bit port (80)
6958 };
[email protected]e0c27be2009-07-15 13:09:356959 const char kSOCKS5OkResponse[] =
6960 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
6961
6962 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066963 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6964 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:356965 MockWrite("GET / HTTP/1.1\r\n"
6966 "Host: www.google.com\r\n"
6967 "Connection: keep-alive\r\n\r\n")
6968 };
6969
6970 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016971 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6972 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:356973 MockRead("HTTP/1.0 200 OK\r\n"),
6974 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6975 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066976 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356977 };
6978
[email protected]31a2bfe2010-02-09 08:03:396979 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6980 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076981 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356982
[email protected]49639fa2011-12-20 23:22:416983 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356984
[email protected]49639fa2011-12-20 23:22:416985 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356986 EXPECT_EQ(ERR_IO_PENDING, rv);
6987
6988 rv = callback.WaitForResult();
6989 EXPECT_EQ(OK, rv);
6990
6991 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506992 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356993
[email protected]029c83b62013-01-24 05:28:206994 LoadTimingInfo load_timing_info;
6995 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6996 TestLoadTimingNotReusedWithPac(load_timing_info,
6997 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6998
[email protected]e0c27be2009-07-15 13:09:356999 std::string response_text;
7000 rv = ReadTransaction(trans.get(), &response_text);
7001 EXPECT_EQ(OK, rv);
7002 EXPECT_EQ("Payload", response_text);
7003}
7004
[email protected]23e482282013-06-14 16:08:027005TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277006 HttpRequestInfo request;
7007 request.method = "GET";
7008 request.url = GURL("https://www.google.com/");
7009 request.load_flags = 0;
7010
[email protected]bb88e1d32013-05-03 23:11:077011 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207012 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7013 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077014 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357015
[email protected]3fe8d2f82013-10-17 08:56:077016 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357017 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357019
[email protected]e0c27be2009-07-15 13:09:357020 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7021 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377022 const unsigned char kSOCKS5OkRequest[] = {
7023 0x05, // Version
7024 0x01, // Command (CONNECT)
7025 0x00, // Reserved.
7026 0x03, // Address type (DOMAINNAME).
7027 0x0E, // Length of domain (14)
7028 // Domain string:
7029 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7030 0x01, 0xBB, // 16-bit port (443)
7031 };
7032
[email protected]e0c27be2009-07-15 13:09:357033 const char kSOCKS5OkResponse[] =
7034 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7035
7036 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067037 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7038 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357039 arraysize(kSOCKS5OkRequest)),
7040 MockWrite("GET / HTTP/1.1\r\n"
7041 "Host: www.google.com\r\n"
7042 "Connection: keep-alive\r\n\r\n")
7043 };
7044
7045 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017046 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7047 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027048 MockRead("HTTP/1.0 200 OK\r\n"),
7049 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7050 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067051 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027052 };
7053
[email protected]31a2bfe2010-02-09 08:03:397054 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7055 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077056 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027057
[email protected]8ddf8322012-02-23 18:08:067058 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027060
[email protected]49639fa2011-12-20 23:22:417061 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027062
[email protected]49639fa2011-12-20 23:22:417063 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027064 EXPECT_EQ(ERR_IO_PENDING, rv);
7065
7066 rv = callback.WaitForResult();
7067 EXPECT_EQ(OK, rv);
7068
7069 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507070 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027071
[email protected]029c83b62013-01-24 05:28:207072 LoadTimingInfo load_timing_info;
7073 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7074 TestLoadTimingNotReusedWithPac(load_timing_info,
7075 CONNECT_TIMING_HAS_SSL_TIMES);
7076
[email protected]3cd17242009-06-23 02:59:027077 std::string response_text;
7078 rv = ReadTransaction(trans.get(), &response_text);
7079 EXPECT_EQ(OK, rv);
7080 EXPECT_EQ("Payload", response_text);
7081}
7082
[email protected]448d4ca52012-03-04 04:12:237083namespace {
7084
[email protected]04e5be32009-06-26 20:00:317085// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067086
7087struct GroupNameTest {
7088 std::string proxy_server;
7089 std::string url;
7090 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187091 bool ssl;
[email protected]2d731a32010-04-29 01:04:067092};
7093
7094scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437095 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077096 SpdySessionDependencies* session_deps_) {
7097 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067098
[email protected]30d4c022013-07-18 22:58:167099 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537100 session->http_server_properties();
7101 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067102 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437103 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067104
7105 return session;
7106}
7107
7108int GroupNameTransactionHelper(
7109 const std::string& url,
7110 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067111 HttpRequestInfo request;
7112 request.method = "GET";
7113 request.url = GURL(url);
7114 request.load_flags = 0;
7115
[email protected]262eec82013-03-19 21:01:367116 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277118
[email protected]49639fa2011-12-20 23:22:417119 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067120
7121 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417122 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067123}
7124
[email protected]448d4ca52012-03-04 04:12:237125} // namespace
7126
[email protected]23e482282013-06-14 16:08:027127TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067128 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317129 {
[email protected]2d731a32010-04-29 01:04:067130 "", // unused
[email protected]04e5be32009-06-26 20:00:317131 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547132 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187133 false,
[email protected]2ff8b312010-04-26 22:20:547134 },
7135 {
[email protected]2d731a32010-04-29 01:04:067136 "", // unused
[email protected]2ff8b312010-04-26 22:20:547137 "http://[2001:1418:13:1::25]/direct",
7138 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187139 false,
[email protected]04e5be32009-06-26 20:00:317140 },
[email protected]04e5be32009-06-26 20:00:317141
7142 // SSL Tests
7143 {
[email protected]2d731a32010-04-29 01:04:067144 "", // unused
[email protected]04e5be32009-06-26 20:00:317145 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027146 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187147 true,
[email protected]04e5be32009-06-26 20:00:317148 },
7149 {
[email protected]2d731a32010-04-29 01:04:067150 "", // unused
7151 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027152 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187153 true,
[email protected]04e5be32009-06-26 20:00:317154 },
7155 {
[email protected]2d731a32010-04-29 01:04:067156 "", // unused
[email protected]2ff8b312010-04-26 22:20:547157 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027158 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187159 true,
[email protected]2ff8b312010-04-26 22:20:547160 },
[email protected]2d731a32010-04-29 01:04:067161 };
[email protected]2ff8b312010-04-26 22:20:547162
[email protected]8e6441ca2010-08-19 05:56:387163 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067164
7165 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077166 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027167 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067168 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437169 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067170
7171 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287172 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7173 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137174 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347175 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447176 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7177 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027178 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7179 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447180 peer.SetClientSocketPoolManager(
7181 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067182
7183 EXPECT_EQ(ERR_IO_PENDING,
7184 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187185 if (tests[i].ssl)
7186 EXPECT_EQ(tests[i].expected_group_name,
7187 ssl_conn_pool->last_group_name_received());
7188 else
7189 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287190 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067191 }
7192
[email protected]2d731a32010-04-29 01:04:067193}
7194
[email protected]23e482282013-06-14 16:08:027195TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067196 const GroupNameTest tests[] = {
7197 {
7198 "http_proxy",
7199 "http://www.google.com/http_proxy_normal",
7200 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187201 false,
[email protected]2d731a32010-04-29 01:04:067202 },
7203
7204 // SSL Tests
7205 {
7206 "http_proxy",
7207 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027208 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187209 true,
[email protected]2d731a32010-04-29 01:04:067210 },
[email protected]af3490e2010-10-16 21:02:297211
[email protected]9faeded92010-04-29 20:03:057212 {
7213 "http_proxy",
7214 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027215 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187216 true,
[email protected]9faeded92010-04-29 20:03:057217 },
[email protected]45499252013-01-23 17:12:567218
7219 {
7220 "http_proxy",
7221 "ftp://ftp.google.com/http_proxy_normal",
7222 "ftp/ftp.google.com:21",
7223 false,
7224 },
[email protected]2d731a32010-04-29 01:04:067225 };
7226
[email protected]8e6441ca2010-08-19 05:56:387227 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067228
7229 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077230 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027231 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067232 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437233 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067234
7235 HttpNetworkSessionPeer peer(session);
7236
[email protected]e60e47a2010-07-14 03:37:187237 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137238 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347239 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137240 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347241 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027242
[email protected]831e4a32013-11-14 02:14:447243 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7244 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027245 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7246 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447247 peer.SetClientSocketPoolManager(
7248 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067249
7250 EXPECT_EQ(ERR_IO_PENDING,
7251 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187252 if (tests[i].ssl)
7253 EXPECT_EQ(tests[i].expected_group_name,
7254 ssl_conn_pool->last_group_name_received());
7255 else
7256 EXPECT_EQ(tests[i].expected_group_name,
7257 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067258 }
[email protected]2d731a32010-04-29 01:04:067259}
7260
[email protected]23e482282013-06-14 16:08:027261TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067262 const GroupNameTest tests[] = {
7263 {
7264 "socks4://socks_proxy:1080",
7265 "http://www.google.com/socks4_direct",
7266 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187267 false,
[email protected]2d731a32010-04-29 01:04:067268 },
7269 {
7270 "socks5://socks_proxy:1080",
7271 "http://www.google.com/socks5_direct",
7272 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187273 false,
[email protected]2d731a32010-04-29 01:04:067274 },
7275
7276 // SSL Tests
7277 {
7278 "socks4://socks_proxy:1080",
7279 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027280 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187281 true,
[email protected]2d731a32010-04-29 01:04:067282 },
7283 {
7284 "socks5://socks_proxy:1080",
7285 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027286 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187287 true,
[email protected]2d731a32010-04-29 01:04:067288 },
[email protected]af3490e2010-10-16 21:02:297289
[email protected]9faeded92010-04-29 20:03:057290 {
7291 "socks4://socks_proxy:1080",
7292 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027293 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187294 true,
[email protected]9faeded92010-04-29 20:03:057295 },
[email protected]04e5be32009-06-26 20:00:317296 };
7297
[email protected]8e6441ca2010-08-19 05:56:387298 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547299
[email protected]04e5be32009-06-26 20:00:317300 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077301 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027302 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067303 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437304 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027305
[email protected]2d731a32010-04-29 01:04:067306 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317307
[email protected]e60e47a2010-07-14 03:37:187308 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137309 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347310 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137311 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347312 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027313
[email protected]831e4a32013-11-14 02:14:447314 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7315 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027316 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7317 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447318 peer.SetClientSocketPoolManager(
7319 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317320
[email protected]262eec82013-03-19 21:01:367321 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317323
[email protected]2d731a32010-04-29 01:04:067324 EXPECT_EQ(ERR_IO_PENDING,
7325 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187326 if (tests[i].ssl)
7327 EXPECT_EQ(tests[i].expected_group_name,
7328 ssl_conn_pool->last_group_name_received());
7329 else
7330 EXPECT_EQ(tests[i].expected_group_name,
7331 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317332 }
7333}
7334
[email protected]23e482282013-06-14 16:08:027335TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277336 HttpRequestInfo request;
7337 request.method = "GET";
7338 request.url = GURL("http://www.google.com/");
7339
[email protected]bb88e1d32013-05-03 23:11:077340 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007341 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327342
[email protected]69719062010-01-05 20:09:217343 // This simulates failure resolving all hostnames; that means we will fail
7344 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077345 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327346
[email protected]3fe8d2f82013-10-17 08:56:077347 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257348 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077349 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257350
[email protected]49639fa2011-12-20 23:22:417351 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257352
[email protected]49639fa2011-12-20 23:22:417353 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257354 EXPECT_EQ(ERR_IO_PENDING, rv);
7355
[email protected]9172a982009-06-06 00:30:257356 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017357 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257358}
7359
[email protected]685af592010-05-11 19:31:247360// Base test to make sure that when the load flags for a request specify to
7361// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027362void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077363 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277364 // Issue a request, asking to bypass the cache(s).
7365 HttpRequestInfo request;
7366 request.method = "GET";
7367 request.load_flags = load_flags;
7368 request.url = GURL("http://www.google.com/");
7369
[email protected]a2c2fb92009-07-18 07:31:047370 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077371 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327372
[email protected]3fe8d2f82013-10-17 08:56:077373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7374 scoped_ptr<HttpTransaction> trans(
7375 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287376
[email protected]6e78dfb2011-07-28 21:34:477377 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287378 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297379 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077380 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107381 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7382 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417383 &addrlist,
7384 callback.callback(),
7385 NULL,
7386 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477387 EXPECT_EQ(ERR_IO_PENDING, rv);
7388 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287389 EXPECT_EQ(OK, rv);
7390
7391 // Verify that it was added to host cache, by doing a subsequent async lookup
7392 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077393 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107394 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7395 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417396 &addrlist,
7397 callback.callback(),
7398 NULL,
7399 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327400 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287401
7402 // Inject a failure the next time that "www.google.com" is resolved. This way
7403 // we can tell if the next lookup hit the cache, or the "network".
7404 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077405 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287406
7407 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7408 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067409 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397410 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077411 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287412
[email protected]3b9cca42009-06-16 01:08:287413 // Run the request.
[email protected]49639fa2011-12-20 23:22:417414 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287415 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417416 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287417
7418 // If we bypassed the cache, we would have gotten a failure while resolving
7419 // "www.google.com".
7420 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7421}
7422
[email protected]685af592010-05-11 19:31:247423// There are multiple load flags that should trigger the host cache bypass.
7424// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027425TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247426 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7427}
7428
[email protected]23e482282013-06-14 16:08:027429TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247430 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7431}
7432
[email protected]23e482282013-06-14 16:08:027433TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247434 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7435}
7436
[email protected]0877e3d2009-10-17 22:29:577437// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027438TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577439 HttpRequestInfo request;
7440 request.method = "GET";
7441 request.url = GURL("http://www.foo.com/");
7442 request.load_flags = 0;
7443
7444 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067445 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577446 };
[email protected]31a2bfe2010-02-09 08:03:397447 StaticSocketDataProvider data(NULL, 0,
7448 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077449 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077450 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577451
[email protected]49639fa2011-12-20 23:22:417452 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577453
7454 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577456
[email protected]49639fa2011-12-20 23:22:417457 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577458 EXPECT_EQ(ERR_IO_PENDING, rv);
7459
7460 rv = callback.WaitForResult();
7461 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7462}
7463
7464// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027465TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577466 HttpRequestInfo request;
7467 request.method = "GET";
7468 request.url = GURL("http://www.foo.com/");
7469 request.load_flags = 0;
7470
7471 MockRead data_reads[] = {
7472 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067473 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577474 };
7475
[email protected]31a2bfe2010-02-09 08:03:397476 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077477 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077478 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577479
[email protected]49639fa2011-12-20 23:22:417480 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577481
7482 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077483 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577484
[email protected]49639fa2011-12-20 23:22:417485 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577486 EXPECT_EQ(ERR_IO_PENDING, rv);
7487
7488 rv = callback.WaitForResult();
7489 EXPECT_EQ(OK, rv);
7490
7491 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507492 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577493
[email protected]90499482013-06-01 00:39:507494 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577495 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7496
7497 std::string response_data;
7498 rv = ReadTransaction(trans.get(), &response_data);
7499 EXPECT_EQ(OK, rv);
7500 EXPECT_EQ("", response_data);
7501}
7502
7503// Make sure that a dropped connection while draining the body for auth
7504// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027505TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577506 HttpRequestInfo request;
7507 request.method = "GET";
7508 request.url = GURL("http://www.google.com/");
7509 request.load_flags = 0;
7510
7511 MockWrite data_writes1[] = {
7512 MockWrite("GET / HTTP/1.1\r\n"
7513 "Host: www.google.com\r\n"
7514 "Connection: keep-alive\r\n\r\n"),
7515 };
7516
7517 MockRead data_reads1[] = {
7518 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7519 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7520 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7521 MockRead("Content-Length: 14\r\n\r\n"),
7522 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067523 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577524 };
7525
[email protected]31a2bfe2010-02-09 08:03:397526 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7527 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077528 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577529
7530 // After calling trans->RestartWithAuth(), this is the request we should
7531 // be issuing -- the final header line contains the credentials.
7532 MockWrite data_writes2[] = {
7533 MockWrite("GET / HTTP/1.1\r\n"
7534 "Host: www.google.com\r\n"
7535 "Connection: keep-alive\r\n"
7536 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7537 };
7538
7539 // Lastly, the server responds with the actual content.
7540 MockRead data_reads2[] = {
7541 MockRead("HTTP/1.1 200 OK\r\n"),
7542 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7543 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067544 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577545 };
7546
[email protected]31a2bfe2010-02-09 08:03:397547 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7548 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077549 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077550 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577551
[email protected]49639fa2011-12-20 23:22:417552 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577553
[email protected]262eec82013-03-19 21:01:367554 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507556
[email protected]49639fa2011-12-20 23:22:417557 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577558 EXPECT_EQ(ERR_IO_PENDING, rv);
7559
7560 rv = callback1.WaitForResult();
7561 EXPECT_EQ(OK, rv);
7562
7563 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507564 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047565 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577566
[email protected]49639fa2011-12-20 23:22:417567 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577568
[email protected]49639fa2011-12-20 23:22:417569 rv = trans->RestartWithAuth(
7570 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577571 EXPECT_EQ(ERR_IO_PENDING, rv);
7572
7573 rv = callback2.WaitForResult();
7574 EXPECT_EQ(OK, rv);
7575
7576 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507577 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577578 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7579 EXPECT_EQ(100, response->headers->GetContentLength());
7580}
7581
7582// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027583TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077584 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577585
7586 HttpRequestInfo request;
7587 request.method = "GET";
7588 request.url = GURL("https://www.google.com/");
7589 request.load_flags = 0;
7590
7591 MockRead proxy_reads[] = {
7592 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067593 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577594 };
7595
[email protected]31a2bfe2010-02-09 08:03:397596 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067597 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577598
[email protected]bb88e1d32013-05-03 23:11:077599 session_deps_.socket_factory->AddSocketDataProvider(&data);
7600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577601
[email protected]49639fa2011-12-20 23:22:417602 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577603
[email protected]bb88e1d32013-05-03 23:11:077604 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577605
[email protected]3fe8d2f82013-10-17 08:56:077606 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577607 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577609
[email protected]49639fa2011-12-20 23:22:417610 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577611 EXPECT_EQ(ERR_IO_PENDING, rv);
7612
7613 rv = callback.WaitForResult();
7614 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7615}
7616
[email protected]23e482282013-06-14 16:08:027617TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467618 HttpRequestInfo request;
7619 request.method = "GET";
7620 request.url = GURL("http://www.google.com/");
7621 request.load_flags = 0;
7622
[email protected]3fe8d2f82013-10-17 08:56:077623 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277624 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277626
[email protected]e22e1362009-11-23 21:31:127627 MockRead data_reads[] = {
7628 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067629 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127630 };
[email protected]9492e4a2010-02-24 00:58:467631
7632 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077633 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467634
[email protected]49639fa2011-12-20 23:22:417635 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467636
[email protected]49639fa2011-12-20 23:22:417637 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467638 EXPECT_EQ(ERR_IO_PENDING, rv);
7639
7640 EXPECT_EQ(OK, callback.WaitForResult());
7641
7642 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507643 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467644
[email protected]90499482013-06-01 00:39:507645 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467646 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7647
7648 std::string response_data;
7649 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237650 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127651}
7652
[email protected]23e482282013-06-14 16:08:027653TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157654 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:527655 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:337656 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217657 UploadFileElementReader::ScopedOverridingContentLengthForTests
7658 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337659
[email protected]b2d26cfd2012-12-11 10:36:067660 ScopedVector<UploadElementReader> element_readers;
7661 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367662 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7663 temp_file_path,
7664 0,
7665 kuint64max,
7666 base::Time()));
[email protected]96c77a72013-09-24 09:49:207667 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277668
7669 HttpRequestInfo request;
7670 request.method = "POST";
7671 request.url = GURL("http://www.google.com/upload");
7672 request.upload_data_stream = &upload_data_stream;
7673 request.load_flags = 0;
7674
[email protected]3fe8d2f82013-10-17 08:56:077675 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277676 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077677 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:337678
7679 MockRead data_reads[] = {
7680 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7681 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067682 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337683 };
[email protected]31a2bfe2010-02-09 08:03:397684 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077685 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337686
[email protected]49639fa2011-12-20 23:22:417687 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337688
[email protected]49639fa2011-12-20 23:22:417689 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337690 EXPECT_EQ(ERR_IO_PENDING, rv);
7691
7692 rv = callback.WaitForResult();
7693 EXPECT_EQ(OK, rv);
7694
7695 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507696 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337697
[email protected]90499482013-06-01 00:39:507698 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337699 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7700
7701 std::string response_data;
7702 rv = ReadTransaction(trans.get(), &response_data);
7703 EXPECT_EQ(OK, rv);
7704 EXPECT_EQ("hello world", response_data);
7705
[email protected]dd3aa792013-07-16 19:10:237706 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:337707}
7708
[email protected]23e482282013-06-14 16:08:027709TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157710 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:527711 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:367712 std::string temp_file_content("Unreadable file.");
7713 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
7714 temp_file_content.length()));
7715 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7716
[email protected]b2d26cfd2012-12-11 10:36:067717 ScopedVector<UploadElementReader> element_readers;
7718 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367719 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7720 temp_file,
7721 0,
7722 kuint64max,
7723 base::Time()));
[email protected]96c77a72013-09-24 09:49:207724 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277725
7726 HttpRequestInfo request;
7727 request.method = "POST";
7728 request.url = GURL("http://www.google.com/upload");
7729 request.upload_data_stream = &upload_data_stream;
7730 request.load_flags = 0;
7731
[email protected]999dd8c2013-11-12 06:45:547732 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:077733 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277734 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077735 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:367736
[email protected]999dd8c2013-11-12 06:45:547737 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367739
[email protected]49639fa2011-12-20 23:22:417740 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:367741
[email protected]49639fa2011-12-20 23:22:417742 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367743 EXPECT_EQ(ERR_IO_PENDING, rv);
7744
7745 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:547746 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:367747
7748 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:547749 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:367750
[email protected]dd3aa792013-07-16 19:10:237751 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367752}
7753
[email protected]02cad5d2013-10-02 08:14:037754TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
7755 class FakeUploadElementReader : public UploadElementReader {
7756 public:
7757 FakeUploadElementReader() {}
7758 virtual ~FakeUploadElementReader() {}
7759
7760 const CompletionCallback& callback() const { return callback_; }
7761
7762 // UploadElementReader overrides:
7763 virtual int Init(const CompletionCallback& callback) OVERRIDE {
7764 callback_ = callback;
7765 return ERR_IO_PENDING;
7766 }
7767 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
7768 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
7769 virtual int Read(IOBuffer* buf,
7770 int buf_length,
7771 const CompletionCallback& callback) OVERRIDE {
7772 return ERR_FAILED;
7773 }
7774
7775 private:
7776 CompletionCallback callback_;
7777 };
7778
7779 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
7780 ScopedVector<UploadElementReader> element_readers;
7781 element_readers.push_back(fake_reader);
7782 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7783
7784 HttpRequestInfo request;
7785 request.method = "POST";
7786 request.url = GURL("http://www.google.com/upload");
7787 request.upload_data_stream = &upload_data_stream;
7788 request.load_flags = 0;
7789
[email protected]3fe8d2f82013-10-17 08:56:077790 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:037791 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077792 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:037793
7794 StaticSocketDataProvider data;
7795 session_deps_.socket_factory->AddSocketDataProvider(&data);
7796
7797 TestCompletionCallback callback;
7798 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7799 EXPECT_EQ(ERR_IO_PENDING, rv);
7800 base::MessageLoop::current()->RunUntilIdle();
7801
7802 // Transaction is pending on request body initialization.
7803 ASSERT_FALSE(fake_reader->callback().is_null());
7804
7805 // Return Init()'s result after the transaction gets destroyed.
7806 trans.reset();
7807 fake_reader->callback().Run(OK); // Should not crash.
7808}
7809
[email protected]aeefc9e82010-02-19 16:18:277810// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:027811TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:277812
7813 HttpRequestInfo request;
7814 request.method = "GET";
7815 request.url = GURL("http://www.google.com/");
7816 request.load_flags = 0;
7817
7818 // First transaction will request a resource and receive a Basic challenge
7819 // with realm="first_realm".
7820 MockWrite data_writes1[] = {
7821 MockWrite("GET / HTTP/1.1\r\n"
7822 "Host: www.google.com\r\n"
7823 "Connection: keep-alive\r\n"
7824 "\r\n"),
7825 };
7826 MockRead data_reads1[] = {
7827 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7828 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7829 "\r\n"),
7830 };
7831
7832 // After calling trans->RestartWithAuth(), provide an Authentication header
7833 // for first_realm. The server will reject and provide a challenge with
7834 // second_realm.
7835 MockWrite data_writes2[] = {
7836 MockWrite("GET / HTTP/1.1\r\n"
7837 "Host: www.google.com\r\n"
7838 "Connection: keep-alive\r\n"
7839 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7840 "\r\n"),
7841 };
7842 MockRead data_reads2[] = {
7843 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7844 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7845 "\r\n"),
7846 };
7847
7848 // This again fails, and goes back to first_realm. Make sure that the
7849 // entry is removed from cache.
7850 MockWrite data_writes3[] = {
7851 MockWrite("GET / HTTP/1.1\r\n"
7852 "Host: www.google.com\r\n"
7853 "Connection: keep-alive\r\n"
7854 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
7855 "\r\n"),
7856 };
7857 MockRead data_reads3[] = {
7858 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7859 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7860 "\r\n"),
7861 };
7862
7863 // Try one last time (with the correct password) and get the resource.
7864 MockWrite data_writes4[] = {
7865 MockWrite("GET / HTTP/1.1\r\n"
7866 "Host: www.google.com\r\n"
7867 "Connection: keep-alive\r\n"
7868 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
7869 "\r\n"),
7870 };
7871 MockRead data_reads4[] = {
7872 MockRead("HTTP/1.1 200 OK\r\n"
7873 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:507874 "Content-Length: 5\r\n"
7875 "\r\n"
7876 "hello"),
[email protected]aeefc9e82010-02-19 16:18:277877 };
7878
7879 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7880 data_writes1, arraysize(data_writes1));
7881 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7882 data_writes2, arraysize(data_writes2));
7883 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7884 data_writes3, arraysize(data_writes3));
7885 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
7886 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:077887 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7888 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7889 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7890 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:277891
[email protected]49639fa2011-12-20 23:22:417892 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:277893
[email protected]3fe8d2f82013-10-17 08:56:077894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:507895 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:507897
[email protected]aeefc9e82010-02-19 16:18:277898 // Issue the first request with Authorize headers. There should be a
7899 // password prompt for first_realm waiting to be filled in after the
7900 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417901 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:277902 EXPECT_EQ(ERR_IO_PENDING, rv);
7903 rv = callback1.WaitForResult();
7904 EXPECT_EQ(OK, rv);
7905 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507906 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047907 const AuthChallengeInfo* challenge = response->auth_challenge.get();
7908 ASSERT_FALSE(challenge == NULL);
7909 EXPECT_FALSE(challenge->is_proxy);
7910 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7911 EXPECT_EQ("first_realm", challenge->realm);
7912 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277913
7914 // Issue the second request with an incorrect password. There should be a
7915 // password prompt for second_realm waiting to be filled in after the
7916 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417917 TestCompletionCallback callback2;
7918 rv = trans->RestartWithAuth(
7919 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:277920 EXPECT_EQ(ERR_IO_PENDING, rv);
7921 rv = callback2.WaitForResult();
7922 EXPECT_EQ(OK, rv);
7923 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507924 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047925 challenge = response->auth_challenge.get();
7926 ASSERT_FALSE(challenge == NULL);
7927 EXPECT_FALSE(challenge->is_proxy);
7928 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7929 EXPECT_EQ("second_realm", challenge->realm);
7930 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277931
7932 // Issue the third request with another incorrect password. There should be
7933 // a password prompt for first_realm waiting to be filled in. If the password
7934 // prompt is not present, it indicates that the HttpAuthCacheEntry for
7935 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:417936 TestCompletionCallback callback3;
7937 rv = trans->RestartWithAuth(
7938 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:277939 EXPECT_EQ(ERR_IO_PENDING, rv);
7940 rv = callback3.WaitForResult();
7941 EXPECT_EQ(OK, rv);
7942 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507943 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047944 challenge = response->auth_challenge.get();
7945 ASSERT_FALSE(challenge == NULL);
7946 EXPECT_FALSE(challenge->is_proxy);
7947 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7948 EXPECT_EQ("first_realm", challenge->realm);
7949 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277950
7951 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:417952 TestCompletionCallback callback4;
7953 rv = trans->RestartWithAuth(
7954 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:277955 EXPECT_EQ(ERR_IO_PENDING, rv);
7956 rv = callback4.WaitForResult();
7957 EXPECT_EQ(OK, rv);
7958 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507959 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:277960 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7961}
7962
[email protected]23e482282013-06-14 16:08:027963TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:037964 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:237965 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:427966
[email protected]8a0fc822013-06-27 20:52:437967 std::string alternate_protocol_http_header =
7968 GetAlternateProtocolHttpHeader();
7969
[email protected]564b4912010-03-09 16:30:427970 MockRead data_reads[] = {
7971 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:437972 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:427973 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067974 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:427975 };
7976
7977 HttpRequestInfo request;
7978 request.method = "GET";
7979 request.url = GURL("http://www.google.com/");
7980 request.load_flags = 0;
7981
7982 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7983
[email protected]bb88e1d32013-05-03 23:11:077984 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:427985
[email protected]49639fa2011-12-20 23:22:417986 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:427987
[email protected]bb88e1d32013-05-03 23:11:077988 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:367989 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507990 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:427991
[email protected]49639fa2011-12-20 23:22:417992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:427993 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:537994
[email protected]2fbaecf22010-07-22 22:20:357995 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]17291a022011-10-10 07:32:537996 const HttpServerProperties& http_server_properties =
7997 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:427998 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:537999 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428000
8001 EXPECT_EQ(OK, callback.WaitForResult());
8002
8003 const HttpResponseInfo* response = trans->GetResponseInfo();
8004 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508005 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428006 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538007 EXPECT_FALSE(response->was_fetched_via_spdy);
8008 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428009
8010 std::string response_data;
8011 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8012 EXPECT_EQ("hello world", response_data);
8013
[email protected]17291a022011-10-10 07:32:538014 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8015 const PortAlternateProtocolPair alternate =
8016 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8017 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428018 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438019 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428020 EXPECT_TRUE(expected_alternate.Equals(alternate));
8021}
8022
[email protected]23e482282013-06-14 16:08:028023TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238024 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388025 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428026
8027 HttpRequestInfo request;
8028 request.method = "GET";
8029 request.url = GURL("http://www.google.com/");
8030 request.load_flags = 0;
8031
[email protected]d973e99a2012-02-17 21:02:368032 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428033 StaticSocketDataProvider first_data;
8034 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078035 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428036
8037 MockRead data_reads[] = {
8038 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8039 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068040 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428041 };
8042 StaticSocketDataProvider second_data(
8043 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078044 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428045
[email protected]bb88e1d32013-05-03 23:11:078046 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428047
[email protected]30d4c022013-07-18 22:58:168048 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538049 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118050 // Port must be < 1024, or the header will be ignored (since initial port was
8051 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538052 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118053 HostPortPair::FromURL(request.url),
8054 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438055 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428056
[email protected]262eec82013-03-19 21:01:368057 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508058 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418059 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428060
[email protected]49639fa2011-12-20 23:22:418061 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428062 EXPECT_EQ(ERR_IO_PENDING, rv);
8063 EXPECT_EQ(OK, callback.WaitForResult());
8064
8065 const HttpResponseInfo* response = trans->GetResponseInfo();
8066 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508067 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428068 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8069
8070 std::string response_data;
8071 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8072 EXPECT_EQ("hello world", response_data);
8073
[email protected]17291a022011-10-10 07:32:538074 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118075 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538076 const PortAlternateProtocolPair alternate =
8077 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118078 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538079 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428080}
8081
[email protected]23e482282013-06-14 16:08:028082TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238083 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118084 // Ensure that we're not allowed to redirect traffic via an alternate
8085 // protocol to an unrestricted (port >= 1024) when the original traffic was
8086 // on a restricted port (port < 1024). Ensure that we can redirect in all
8087 // other cases.
8088 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118089
8090 HttpRequestInfo restricted_port_request;
8091 restricted_port_request.method = "GET";
8092 restricted_port_request.url = GURL("http://www.google.com:1023/");
8093 restricted_port_request.load_flags = 0;
8094
[email protected]d973e99a2012-02-17 21:02:368095 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118096 StaticSocketDataProvider first_data;
8097 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078098 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118099
8100 MockRead data_reads[] = {
8101 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8102 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068103 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118104 };
8105 StaticSocketDataProvider second_data(
8106 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078107 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118108
[email protected]bb88e1d32013-05-03 23:11:078109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118110
[email protected]30d4c022013-07-18 22:58:168111 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538112 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118113 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538114 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118115 HostPortPair::FromURL(restricted_port_request.url),
8116 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438117 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118118
[email protected]262eec82013-03-19 21:01:368119 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418121 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118122
[email protected]49639fa2011-12-20 23:22:418123 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368124 &restricted_port_request,
8125 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118126 EXPECT_EQ(ERR_IO_PENDING, rv);
8127 // Invalid change to unrestricted port should fail.
8128 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198129}
[email protected]3912662a32011-10-04 00:51:118130
[email protected]23e482282013-06-14 16:08:028131TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198132 AlternateProtocolPortRestrictedPermitted) {
8133 // Ensure that we're allowed to redirect traffic via an alternate
8134 // protocol to an unrestricted (port >= 1024) when the original traffic was
8135 // on a restricted port (port < 1024) if we set
8136 // enable_user_alternate_protocol_ports.
8137
8138 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078139 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198140
8141 HttpRequestInfo restricted_port_request;
8142 restricted_port_request.method = "GET";
8143 restricted_port_request.url = GURL("http://www.google.com:1023/");
8144 restricted_port_request.load_flags = 0;
8145
8146 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8147 StaticSocketDataProvider first_data;
8148 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078149 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198150
8151 MockRead data_reads[] = {
8152 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8153 MockRead("hello world"),
8154 MockRead(ASYNC, OK),
8155 };
8156 StaticSocketDataProvider second_data(
8157 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078158 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198159
[email protected]bb88e1d32013-05-03 23:11:078160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198161
[email protected]30d4c022013-07-18 22:58:168162 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198163 session->http_server_properties();
8164 const int kUnrestrictedAlternatePort = 1024;
8165 http_server_properties->SetAlternateProtocol(
8166 HostPortPair::FromURL(restricted_port_request.url),
8167 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438168 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198169
[email protected]262eec82013-03-19 21:01:368170 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198172 TestCompletionCallback callback;
8173
8174 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368175 &restricted_port_request,
8176 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198177 // Change to unrestricted port should succeed.
8178 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118179}
8180
[email protected]23e482282013-06-14 16:08:028181TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238182 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118183 // Ensure that we're not allowed to redirect traffic via an alternate
8184 // protocol to an unrestricted (port >= 1024) when the original traffic was
8185 // on a restricted port (port < 1024). Ensure that we can redirect in all
8186 // other cases.
8187 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118188
8189 HttpRequestInfo restricted_port_request;
8190 restricted_port_request.method = "GET";
8191 restricted_port_request.url = GURL("http://www.google.com:1023/");
8192 restricted_port_request.load_flags = 0;
8193
[email protected]d973e99a2012-02-17 21:02:368194 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118195 StaticSocketDataProvider first_data;
8196 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078197 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118198
8199 MockRead data_reads[] = {
8200 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8201 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068202 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118203 };
8204 StaticSocketDataProvider second_data(
8205 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078206 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118207
[email protected]bb88e1d32013-05-03 23:11:078208 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118209
[email protected]30d4c022013-07-18 22:58:168210 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538211 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118212 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538213 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118214 HostPortPair::FromURL(restricted_port_request.url),
8215 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438216 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118217
[email protected]262eec82013-03-19 21:01:368218 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418220 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118221
[email protected]49639fa2011-12-20 23:22:418222 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368223 &restricted_port_request,
8224 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118225 EXPECT_EQ(ERR_IO_PENDING, rv);
8226 // Valid change to restricted port should pass.
8227 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118228}
8229
[email protected]23e482282013-06-14 16:08:028230TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238231 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118232 // Ensure that we're not allowed to redirect traffic via an alternate
8233 // protocol to an unrestricted (port >= 1024) when the original traffic was
8234 // on a restricted port (port < 1024). Ensure that we can redirect in all
8235 // other cases.
8236 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118237
8238 HttpRequestInfo unrestricted_port_request;
8239 unrestricted_port_request.method = "GET";
8240 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8241 unrestricted_port_request.load_flags = 0;
8242
[email protected]d973e99a2012-02-17 21:02:368243 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118244 StaticSocketDataProvider first_data;
8245 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078246 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118247
8248 MockRead data_reads[] = {
8249 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8250 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068251 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118252 };
8253 StaticSocketDataProvider second_data(
8254 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078255 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118256
[email protected]bb88e1d32013-05-03 23:11:078257 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118258
[email protected]30d4c022013-07-18 22:58:168259 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538260 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118261 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538262 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118263 HostPortPair::FromURL(unrestricted_port_request.url),
8264 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438265 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118266
[email protected]262eec82013-03-19 21:01:368267 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418269 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118270
[email protected]49639fa2011-12-20 23:22:418271 int rv = trans->Start(
8272 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118273 EXPECT_EQ(ERR_IO_PENDING, rv);
8274 // Valid change to restricted port should pass.
8275 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118276}
8277
[email protected]23e482282013-06-14 16:08:028278TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238279 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118280 // Ensure that we're not allowed to redirect traffic via an alternate
8281 // protocol to an unrestricted (port >= 1024) when the original traffic was
8282 // on a restricted port (port < 1024). Ensure that we can redirect in all
8283 // other cases.
8284 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118285
8286 HttpRequestInfo unrestricted_port_request;
8287 unrestricted_port_request.method = "GET";
8288 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8289 unrestricted_port_request.load_flags = 0;
8290
[email protected]d973e99a2012-02-17 21:02:368291 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118292 StaticSocketDataProvider first_data;
8293 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078294 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118295
8296 MockRead data_reads[] = {
8297 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8298 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068299 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118300 };
8301 StaticSocketDataProvider second_data(
8302 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078303 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118304
[email protected]bb88e1d32013-05-03 23:11:078305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118306
[email protected]30d4c022013-07-18 22:58:168307 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538308 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118309 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538310 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118311 HostPortPair::FromURL(unrestricted_port_request.url),
8312 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438313 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118314
[email protected]262eec82013-03-19 21:01:368315 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508316 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418317 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118318
[email protected]49639fa2011-12-20 23:22:418319 int rv = trans->Start(
8320 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118321 EXPECT_EQ(ERR_IO_PENDING, rv);
8322 // Valid change to an unrestricted port should pass.
8323 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118324}
8325
[email protected]23e482282013-06-14 16:08:028326TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238327 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028328 // Ensure that we're not allowed to redirect traffic via an alternate
8329 // protocol to an unsafe port, and that we resume the second
8330 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8331 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028332
8333 HttpRequestInfo request;
8334 request.method = "GET";
8335 request.url = GURL("http://www.google.com/");
8336 request.load_flags = 0;
8337
8338 // The alternate protocol request will error out before we attempt to connect,
8339 // so only the standard HTTP request will try to connect.
8340 MockRead data_reads[] = {
8341 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8342 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068343 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028344 };
8345 StaticSocketDataProvider data(
8346 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078347 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028348
[email protected]bb88e1d32013-05-03 23:11:078349 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028350
[email protected]30d4c022013-07-18 22:58:168351 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028352 session->http_server_properties();
8353 const int kUnsafePort = 7;
8354 http_server_properties->SetAlternateProtocol(
8355 HostPortPair::FromURL(request.url),
8356 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438357 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028358
[email protected]262eec82013-03-19 21:01:368359 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508360 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028361 TestCompletionCallback callback;
8362
8363 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8364 EXPECT_EQ(ERR_IO_PENDING, rv);
8365 // The HTTP request should succeed.
8366 EXPECT_EQ(OK, callback.WaitForResult());
8367
8368 // Disable alternate protocol before the asserts.
8369 HttpStreamFactory::set_use_alternate_protocols(false);
8370
8371 const HttpResponseInfo* response = trans->GetResponseInfo();
8372 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508373 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028374 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8375
8376 std::string response_data;
8377 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8378 EXPECT_EQ("hello world", response_data);
8379}
8380
[email protected]23e482282013-06-14 16:08:028381TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388382 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038383 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548384
8385 HttpRequestInfo request;
8386 request.method = "GET";
8387 request.url = GURL("http://www.google.com/");
8388 request.load_flags = 0;
8389
[email protected]8a0fc822013-06-27 20:52:438390 std::string alternate_protocol_http_header =
8391 GetAlternateProtocolHttpHeader();
8392
[email protected]2ff8b312010-04-26 22:20:548393 MockRead data_reads[] = {
8394 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438395 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548396 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178397 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8398 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548399 };
8400
8401 StaticSocketDataProvider first_transaction(
8402 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078403 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548404
[email protected]8ddf8322012-02-23 18:08:068405 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028406 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548408
[email protected]cdf8f7e72013-05-23 10:56:468409 scoped_ptr<SpdyFrame> req(
8410 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138411 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548412
[email protected]23e482282013-06-14 16:08:028413 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8414 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548415 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138416 CreateMockRead(*resp),
8417 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068418 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548419 };
8420
[email protected]dd54bd82012-07-19 23:44:578421 DelayedSocketData spdy_data(
8422 1, // wait for one write to finish before reading.
8423 spdy_reads, arraysize(spdy_reads),
8424 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078425 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548426
[email protected]d973e99a2012-02-17 21:02:368427 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558428 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8429 NULL, 0, NULL, 0);
8430 hanging_non_alternate_protocol_socket.set_connect_data(
8431 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078432 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558433 &hanging_non_alternate_protocol_socket);
8434
[email protected]49639fa2011-12-20 23:22:418435 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548436
[email protected]bb88e1d32013-05-03 23:11:078437 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368438 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508439 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548440
[email protected]49639fa2011-12-20 23:22:418441 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548442 EXPECT_EQ(ERR_IO_PENDING, rv);
8443 EXPECT_EQ(OK, callback.WaitForResult());
8444
8445 const HttpResponseInfo* response = trans->GetResponseInfo();
8446 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508447 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548448 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8449
8450 std::string response_data;
8451 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8452 EXPECT_EQ("hello world", response_data);
8453
[email protected]90499482013-06-01 00:39:508454 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548455
[email protected]49639fa2011-12-20 23:22:418456 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548457 EXPECT_EQ(ERR_IO_PENDING, rv);
8458 EXPECT_EQ(OK, callback.WaitForResult());
8459
8460 response = trans->GetResponseInfo();
8461 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508462 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548463 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538464 EXPECT_TRUE(response->was_fetched_via_spdy);
8465 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548466
8467 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8468 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548469}
8470
[email protected]23e482282013-06-14 16:08:028471TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558472 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038473 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558474
8475 HttpRequestInfo request;
8476 request.method = "GET";
8477 request.url = GURL("http://www.google.com/");
8478 request.load_flags = 0;
8479
[email protected]8a0fc822013-06-27 20:52:438480 std::string alternate_protocol_http_header =
8481 GetAlternateProtocolHttpHeader();
8482
[email protected]2d6728692011-03-12 01:39:558483 MockRead data_reads[] = {
8484 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438485 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558486 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178487 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068488 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558489 };
8490
8491 StaticSocketDataProvider first_transaction(
8492 data_reads, arraysize(data_reads), NULL, 0);
8493 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078494 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558495
[email protected]d973e99a2012-02-17 21:02:368496 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558497 StaticSocketDataProvider hanging_socket(
8498 NULL, 0, NULL, 0);
8499 hanging_socket.set_connect_data(never_finishing_connect);
8500 // Socket 2 and 3 are the hanging Alternate-Protocol and
8501 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078502 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8503 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558504
[email protected]8ddf8322012-02-23 18:08:068505 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028506 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558508
[email protected]cdf8f7e72013-05-23 10:56:468509 scoped_ptr<SpdyFrame> req1(
8510 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8511 scoped_ptr<SpdyFrame> req2(
8512 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558513 MockWrite spdy_writes[] = {
8514 CreateMockWrite(*req1),
8515 CreateMockWrite(*req2),
8516 };
[email protected]23e482282013-06-14 16:08:028517 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8518 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8519 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8520 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558521 MockRead spdy_reads[] = {
8522 CreateMockRead(*resp1),
8523 CreateMockRead(*data1),
8524 CreateMockRead(*resp2),
8525 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068526 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558527 };
8528
[email protected]dd54bd82012-07-19 23:44:578529 DelayedSocketData spdy_data(
8530 2, // wait for writes to finish before reading.
8531 spdy_reads, arraysize(spdy_reads),
8532 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558533 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078534 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558535
8536 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078537 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558538
[email protected]bb88e1d32013-05-03 23:11:078539 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418540 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508541 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558542
[email protected]49639fa2011-12-20 23:22:418543 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558544 EXPECT_EQ(ERR_IO_PENDING, rv);
8545 EXPECT_EQ(OK, callback1.WaitForResult());
8546
8547 const HttpResponseInfo* response = trans1.GetResponseInfo();
8548 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508549 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558550 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8551
8552 std::string response_data;
8553 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8554 EXPECT_EQ("hello world", response_data);
8555
[email protected]49639fa2011-12-20 23:22:418556 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508557 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418558 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558559 EXPECT_EQ(ERR_IO_PENDING, rv);
8560
[email protected]49639fa2011-12-20 23:22:418561 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508562 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418563 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558564 EXPECT_EQ(ERR_IO_PENDING, rv);
8565
8566 EXPECT_EQ(OK, callback2.WaitForResult());
8567 EXPECT_EQ(OK, callback3.WaitForResult());
8568
8569 response = trans2.GetResponseInfo();
8570 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508571 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558572 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8573 EXPECT_TRUE(response->was_fetched_via_spdy);
8574 EXPECT_TRUE(response->was_npn_negotiated);
8575 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8576 EXPECT_EQ("hello!", response_data);
8577
8578 response = trans3.GetResponseInfo();
8579 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508580 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558581 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8582 EXPECT_TRUE(response->was_fetched_via_spdy);
8583 EXPECT_TRUE(response->was_npn_negotiated);
8584 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8585 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558586}
8587
[email protected]23e482282013-06-14 16:08:028588TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558589 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038590 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558591
8592 HttpRequestInfo request;
8593 request.method = "GET";
8594 request.url = GURL("http://www.google.com/");
8595 request.load_flags = 0;
8596
[email protected]8a0fc822013-06-27 20:52:438597 std::string alternate_protocol_http_header =
8598 GetAlternateProtocolHttpHeader();
8599
[email protected]2d6728692011-03-12 01:39:558600 MockRead data_reads[] = {
8601 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438602 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558603 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178604 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068605 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558606 };
8607
8608 StaticSocketDataProvider first_transaction(
8609 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078610 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558611
[email protected]8ddf8322012-02-23 18:08:068612 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028613 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558615
[email protected]d973e99a2012-02-17 21:02:368616 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558617 StaticSocketDataProvider hanging_alternate_protocol_socket(
8618 NULL, 0, NULL, 0);
8619 hanging_alternate_protocol_socket.set_connect_data(
8620 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078621 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558622 &hanging_alternate_protocol_socket);
8623
8624 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078625 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558626
[email protected]49639fa2011-12-20 23:22:418627 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558628
[email protected]bb88e1d32013-05-03 23:11:078629 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368630 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558632
[email protected]49639fa2011-12-20 23:22:418633 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558634 EXPECT_EQ(ERR_IO_PENDING, rv);
8635 EXPECT_EQ(OK, callback.WaitForResult());
8636
8637 const HttpResponseInfo* response = trans->GetResponseInfo();
8638 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508639 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558640 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8641
8642 std::string response_data;
8643 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8644 EXPECT_EQ("hello world", response_data);
8645
[email protected]90499482013-06-01 00:39:508646 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558647
[email protected]49639fa2011-12-20 23:22:418648 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558649 EXPECT_EQ(ERR_IO_PENDING, rv);
8650 EXPECT_EQ(OK, callback.WaitForResult());
8651
8652 response = trans->GetResponseInfo();
8653 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508654 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558655 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8656 EXPECT_FALSE(response->was_fetched_via_spdy);
8657 EXPECT_FALSE(response->was_npn_negotiated);
8658
8659 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8660 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558661}
8662
[email protected]631f1322010-04-30 17:59:118663class CapturingProxyResolver : public ProxyResolver {
8664 public:
8665 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8666 virtual ~CapturingProxyResolver() {}
8667
8668 virtual int GetProxyForURL(const GURL& url,
8669 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318670 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118671 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168672 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408673 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8674 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428675 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118676 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428677 return OK;
[email protected]631f1322010-04-30 17:59:118678 }
8679
[email protected]46fadfd2013-02-06 09:40:168680 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118681 NOTREACHED();
8682 }
8683
[email protected]f2c971f2011-11-08 00:33:178684 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8685 NOTREACHED();
8686 return LOAD_STATE_IDLE;
8687 }
8688
[email protected]46fadfd2013-02-06 09:40:168689 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408690 NOTREACHED();
8691 }
8692
[email protected]24476402010-07-20 20:55:178693 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168694 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428695 return OK;
[email protected]631f1322010-04-30 17:59:118696 }
8697
[email protected]24476402010-07-20 20:55:178698 const std::vector<GURL>& resolved() const { return resolved_; }
8699
8700 private:
[email protected]631f1322010-04-30 17:59:118701 std::vector<GURL> resolved_;
8702
8703 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8704};
8705
[email protected]23e482282013-06-14 16:08:028706TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238707 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388708 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038709 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118710
8711 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428712 proxy_config.set_auto_detect(true);
8713 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118714
[email protected]631f1322010-04-30 17:59:118715 CapturingProxyResolver* capturing_proxy_resolver =
8716 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078717 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388718 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8719 NULL));
[email protected]029c83b62013-01-24 05:28:208720 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078721 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118722
8723 HttpRequestInfo request;
8724 request.method = "GET";
8725 request.url = GURL("http://www.google.com/");
8726 request.load_flags = 0;
8727
[email protected]8a0fc822013-06-27 20:52:438728 std::string alternate_protocol_http_header =
8729 GetAlternateProtocolHttpHeader();
8730
[email protected]631f1322010-04-30 17:59:118731 MockRead data_reads[] = {
8732 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438733 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118734 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178735 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068736 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118737 };
8738
8739 StaticSocketDataProvider first_transaction(
8740 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078741 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:118742
[email protected]8ddf8322012-02-23 18:08:068743 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028744 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078745 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:118746
[email protected]cdf8f7e72013-05-23 10:56:468747 scoped_ptr<SpdyFrame> req(
8748 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:118749 MockWrite spdy_writes[] = {
8750 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8751 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:428752 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:468753 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:118754 };
8755
[email protected]d911f1b2010-05-05 22:39:428756 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8757
[email protected]23e482282013-06-14 16:08:028758 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8759 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:118760 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068761 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:138762 CreateMockRead(*resp.get(), 4), // 2, 4
8763 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:068764 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:118765 };
8766
[email protected]dd54bd82012-07-19 23:44:578767 OrderedSocketData spdy_data(
8768 spdy_reads, arraysize(spdy_reads),
8769 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078770 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:118771
[email protected]d973e99a2012-02-17 21:02:368772 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558773 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8774 NULL, 0, NULL, 0);
8775 hanging_non_alternate_protocol_socket.set_connect_data(
8776 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078777 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558778 &hanging_non_alternate_protocol_socket);
8779
[email protected]49639fa2011-12-20 23:22:418780 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:118781
[email protected]bb88e1d32013-05-03 23:11:078782 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368783 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118785
[email protected]49639fa2011-12-20 23:22:418786 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118787 EXPECT_EQ(ERR_IO_PENDING, rv);
8788 EXPECT_EQ(OK, callback.WaitForResult());
8789
8790 const HttpResponseInfo* response = trans->GetResponseInfo();
8791 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508792 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118793 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538794 EXPECT_FALSE(response->was_fetched_via_spdy);
8795 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118796
8797 std::string response_data;
8798 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8799 EXPECT_EQ("hello world", response_data);
8800
[email protected]90499482013-06-01 00:39:508801 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118802
[email protected]49639fa2011-12-20 23:22:418803 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118804 EXPECT_EQ(ERR_IO_PENDING, rv);
8805 EXPECT_EQ(OK, callback.WaitForResult());
8806
8807 response = trans->GetResponseInfo();
8808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508809 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538811 EXPECT_TRUE(response->was_fetched_via_spdy);
8812 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118813
8814 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8815 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558816 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:428817 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:118818 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:428819 EXPECT_EQ("https://www.google.com/",
8820 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:118821
[email protected]029c83b62013-01-24 05:28:208822 LoadTimingInfo load_timing_info;
8823 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8824 TestLoadTimingNotReusedWithPac(load_timing_info,
8825 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:118826}
[email protected]631f1322010-04-30 17:59:118827
[email protected]23e482282013-06-14 16:08:028828TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:548829 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:388830 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038831 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548832
8833 HttpRequestInfo request;
8834 request.method = "GET";
8835 request.url = GURL("http://www.google.com/");
8836 request.load_flags = 0;
8837
[email protected]8a0fc822013-06-27 20:52:438838 std::string alternate_protocol_http_header =
8839 GetAlternateProtocolHttpHeader();
8840
[email protected]2ff8b312010-04-26 22:20:548841 MockRead data_reads[] = {
8842 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438843 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548844 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068845 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:548846 };
8847
8848 StaticSocketDataProvider first_transaction(
8849 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078850 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548851
[email protected]8ddf8322012-02-23 18:08:068852 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028853 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078854 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548855
[email protected]cdf8f7e72013-05-23 10:56:468856 scoped_ptr<SpdyFrame> req(
8857 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138858 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548859
[email protected]23e482282013-06-14 16:08:028860 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8861 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548862 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138863 CreateMockRead(*resp),
8864 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068865 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548866 };
8867
[email protected]dd54bd82012-07-19 23:44:578868 DelayedSocketData spdy_data(
8869 1, // wait for one write to finish before reading.
8870 spdy_reads, arraysize(spdy_reads),
8871 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078872 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548873
[email protected]83039bb2011-12-09 18:43:558874 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548875
[email protected]bb88e1d32013-05-03 23:11:078876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:548877
[email protected]262eec82013-03-19 21:01:368878 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508879 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548880
[email protected]49639fa2011-12-20 23:22:418881 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548882 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418883 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548884
8885 const HttpResponseInfo* response = trans->GetResponseInfo();
8886 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508887 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548888 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8889
8890 std::string response_data;
8891 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8892 EXPECT_EQ("hello world", response_data);
8893
8894 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:388895 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:408896 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
8897 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:278898 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:268899 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:388900
[email protected]90499482013-06-01 00:39:508901 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548902
[email protected]49639fa2011-12-20 23:22:418903 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548904 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418905 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548906
8907 response = trans->GetResponseInfo();
8908 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508909 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548910 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538911 EXPECT_TRUE(response->was_fetched_via_spdy);
8912 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548913
8914 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8915 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:428916}
8917
[email protected]044de0642010-06-17 10:42:158918// GenerateAuthToken is a mighty big test.
8919// It tests all permutation of GenerateAuthToken behavior:
8920// - Synchronous and Asynchronous completion.
8921// - OK or error on completion.
8922// - Direct connection, non-authenticating proxy, and authenticating proxy.
8923// - HTTP or HTTPS backend (to include proxy tunneling).
8924// - Non-authenticating and authenticating backend.
8925//
[email protected]fe3b7dc2012-02-03 19:52:098926// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:158927// problems generating an auth token for an authenticating proxy, we don't
8928// need to test all permutations of the backend server).
8929//
8930// The test proceeds by going over each of the configuration cases, and
8931// potentially running up to three rounds in each of the tests. The TestConfig
8932// specifies both the configuration for the test as well as the expectations
8933// for the results.
[email protected]23e482282013-06-14 16:08:028934TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:508935 static const char kServer[] = "http://www.example.com";
8936 static const char kSecureServer[] = "https://www.example.com";
8937 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:158938 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
8939
8940 enum AuthTiming {
8941 AUTH_NONE,
8942 AUTH_SYNC,
8943 AUTH_ASYNC,
8944 };
8945
8946 const MockWrite kGet(
8947 "GET / HTTP/1.1\r\n"
8948 "Host: www.example.com\r\n"
8949 "Connection: keep-alive\r\n\r\n");
8950 const MockWrite kGetProxy(
8951 "GET http://www.example.com/ HTTP/1.1\r\n"
8952 "Host: www.example.com\r\n"
8953 "Proxy-Connection: keep-alive\r\n\r\n");
8954 const MockWrite kGetAuth(
8955 "GET / HTTP/1.1\r\n"
8956 "Host: www.example.com\r\n"
8957 "Connection: keep-alive\r\n"
8958 "Authorization: auth_token\r\n\r\n");
8959 const MockWrite kGetProxyAuth(
8960 "GET http://www.example.com/ HTTP/1.1\r\n"
8961 "Host: www.example.com\r\n"
8962 "Proxy-Connection: keep-alive\r\n"
8963 "Proxy-Authorization: auth_token\r\n\r\n");
8964 const MockWrite kGetAuthThroughProxy(
8965 "GET http://www.example.com/ HTTP/1.1\r\n"
8966 "Host: www.example.com\r\n"
8967 "Proxy-Connection: keep-alive\r\n"
8968 "Authorization: auth_token\r\n\r\n");
8969 const MockWrite kGetAuthWithProxyAuth(
8970 "GET http://www.example.com/ HTTP/1.1\r\n"
8971 "Host: www.example.com\r\n"
8972 "Proxy-Connection: keep-alive\r\n"
8973 "Proxy-Authorization: auth_token\r\n"
8974 "Authorization: auth_token\r\n\r\n");
8975 const MockWrite kConnect(
8976 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8977 "Host: www.example.com\r\n"
8978 "Proxy-Connection: keep-alive\r\n\r\n");
8979 const MockWrite kConnectProxyAuth(
8980 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8981 "Host: www.example.com\r\n"
8982 "Proxy-Connection: keep-alive\r\n"
8983 "Proxy-Authorization: auth_token\r\n\r\n");
8984
8985 const MockRead kSuccess(
8986 "HTTP/1.1 200 OK\r\n"
8987 "Content-Type: text/html; charset=iso-8859-1\r\n"
8988 "Content-Length: 3\r\n\r\n"
8989 "Yes");
8990 const MockRead kFailure(
8991 "Should not be called.");
8992 const MockRead kServerChallenge(
8993 "HTTP/1.1 401 Unauthorized\r\n"
8994 "WWW-Authenticate: Mock realm=server\r\n"
8995 "Content-Type: text/html; charset=iso-8859-1\r\n"
8996 "Content-Length: 14\r\n\r\n"
8997 "Unauthorized\r\n");
8998 const MockRead kProxyChallenge(
8999 "HTTP/1.1 407 Unauthorized\r\n"
9000 "Proxy-Authenticate: Mock realm=proxy\r\n"
9001 "Proxy-Connection: close\r\n"
9002 "Content-Type: text/html; charset=iso-8859-1\r\n"
9003 "Content-Length: 14\r\n\r\n"
9004 "Unauthorized\r\n");
9005 const MockRead kProxyConnected(
9006 "HTTP/1.1 200 Connection Established\r\n\r\n");
9007
9008 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9009 // no constructors, but the C++ compiler on Windows warns about
9010 // unspecified data in compound literals. So, moved to using constructors,
9011 // and TestRound's created with the default constructor should not be used.
9012 struct TestRound {
9013 TestRound()
9014 : expected_rv(ERR_UNEXPECTED),
9015 extra_write(NULL),
9016 extra_read(NULL) {
9017 }
9018 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9019 int expected_rv_arg)
9020 : write(write_arg),
9021 read(read_arg),
9022 expected_rv(expected_rv_arg),
9023 extra_write(NULL),
9024 extra_read(NULL) {
9025 }
9026 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9027 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019028 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159029 : write(write_arg),
9030 read(read_arg),
9031 expected_rv(expected_rv_arg),
9032 extra_write(extra_write_arg),
9033 extra_read(extra_read_arg) {
9034 }
9035 MockWrite write;
9036 MockRead read;
9037 int expected_rv;
9038 const MockWrite* extra_write;
9039 const MockRead* extra_read;
9040 };
9041
9042 static const int kNoSSL = 500;
9043
9044 struct TestConfig {
9045 const char* proxy_url;
9046 AuthTiming proxy_auth_timing;
9047 int proxy_auth_rv;
9048 const char* server_url;
9049 AuthTiming server_auth_timing;
9050 int server_auth_rv;
9051 int num_auth_rounds;
9052 int first_ssl_round;
9053 TestRound rounds[3];
9054 } test_configs[] = {
9055 // Non-authenticating HTTP server with a direct connection.
9056 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9057 { TestRound(kGet, kSuccess, OK)}},
9058 // Authenticating HTTP server with a direct connection.
9059 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9060 { TestRound(kGet, kServerChallenge, OK),
9061 TestRound(kGetAuth, kSuccess, OK)}},
9062 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9063 { TestRound(kGet, kServerChallenge, OK),
9064 TestRound(kGetAuth, kFailure, kAuthErr)}},
9065 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9066 { TestRound(kGet, kServerChallenge, OK),
9067 TestRound(kGetAuth, kSuccess, OK)}},
9068 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9069 { TestRound(kGet, kServerChallenge, OK),
9070 TestRound(kGetAuth, kFailure, kAuthErr)}},
9071 // Non-authenticating HTTP server through a non-authenticating proxy.
9072 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9073 { TestRound(kGetProxy, kSuccess, OK)}},
9074 // Authenticating HTTP server through a non-authenticating proxy.
9075 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9076 { TestRound(kGetProxy, kServerChallenge, OK),
9077 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9078 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9079 { TestRound(kGetProxy, kServerChallenge, OK),
9080 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9081 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9082 { TestRound(kGetProxy, kServerChallenge, OK),
9083 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9084 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9085 { TestRound(kGetProxy, kServerChallenge, OK),
9086 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9087 // Non-authenticating HTTP server through an authenticating proxy.
9088 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9089 { TestRound(kGetProxy, kProxyChallenge, OK),
9090 TestRound(kGetProxyAuth, kSuccess, OK)}},
9091 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9092 { TestRound(kGetProxy, kProxyChallenge, OK),
9093 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9094 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9095 { TestRound(kGetProxy, kProxyChallenge, OK),
9096 TestRound(kGetProxyAuth, kSuccess, OK)}},
9097 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9098 { TestRound(kGetProxy, kProxyChallenge, OK),
9099 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9100 // Authenticating HTTP server through an authenticating proxy.
9101 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9102 { TestRound(kGetProxy, kProxyChallenge, OK),
9103 TestRound(kGetProxyAuth, kServerChallenge, OK),
9104 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9105 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9106 { TestRound(kGetProxy, kProxyChallenge, OK),
9107 TestRound(kGetProxyAuth, kServerChallenge, OK),
9108 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9109 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9110 { TestRound(kGetProxy, kProxyChallenge, OK),
9111 TestRound(kGetProxyAuth, kServerChallenge, OK),
9112 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9113 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9114 { TestRound(kGetProxy, kProxyChallenge, OK),
9115 TestRound(kGetProxyAuth, kServerChallenge, OK),
9116 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9117 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9118 { TestRound(kGetProxy, kProxyChallenge, OK),
9119 TestRound(kGetProxyAuth, kServerChallenge, OK),
9120 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9121 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9122 { TestRound(kGetProxy, kProxyChallenge, OK),
9123 TestRound(kGetProxyAuth, kServerChallenge, OK),
9124 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9125 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9126 { TestRound(kGetProxy, kProxyChallenge, OK),
9127 TestRound(kGetProxyAuth, kServerChallenge, OK),
9128 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9129 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9130 { TestRound(kGetProxy, kProxyChallenge, OK),
9131 TestRound(kGetProxyAuth, kServerChallenge, OK),
9132 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9133 // Non-authenticating HTTPS server with a direct connection.
9134 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9135 { TestRound(kGet, kSuccess, OK)}},
9136 // Authenticating HTTPS server with a direct connection.
9137 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9138 { TestRound(kGet, kServerChallenge, OK),
9139 TestRound(kGetAuth, kSuccess, OK)}},
9140 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9141 { TestRound(kGet, kServerChallenge, OK),
9142 TestRound(kGetAuth, kFailure, kAuthErr)}},
9143 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9144 { TestRound(kGet, kServerChallenge, OK),
9145 TestRound(kGetAuth, kSuccess, OK)}},
9146 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9147 { TestRound(kGet, kServerChallenge, OK),
9148 TestRound(kGetAuth, kFailure, kAuthErr)}},
9149 // Non-authenticating HTTPS server with a non-authenticating proxy.
9150 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9151 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9152 // Authenticating HTTPS server through a non-authenticating proxy.
9153 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9154 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9155 TestRound(kGetAuth, kSuccess, OK)}},
9156 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9157 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9158 TestRound(kGetAuth, kFailure, kAuthErr)}},
9159 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9160 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9161 TestRound(kGetAuth, kSuccess, OK)}},
9162 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9163 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9164 TestRound(kGetAuth, kFailure, kAuthErr)}},
9165 // Non-Authenticating HTTPS server through an authenticating proxy.
9166 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9167 { TestRound(kConnect, kProxyChallenge, OK),
9168 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9169 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9170 { TestRound(kConnect, kProxyChallenge, OK),
9171 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9172 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9173 { TestRound(kConnect, kProxyChallenge, OK),
9174 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9175 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9176 { TestRound(kConnect, kProxyChallenge, OK),
9177 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9178 // Authenticating HTTPS server through an authenticating proxy.
9179 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9180 { TestRound(kConnect, kProxyChallenge, OK),
9181 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9182 &kGet, &kServerChallenge),
9183 TestRound(kGetAuth, kSuccess, OK)}},
9184 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9185 { TestRound(kConnect, kProxyChallenge, OK),
9186 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9187 &kGet, &kServerChallenge),
9188 TestRound(kGetAuth, kFailure, kAuthErr)}},
9189 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9190 { TestRound(kConnect, kProxyChallenge, OK),
9191 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9192 &kGet, &kServerChallenge),
9193 TestRound(kGetAuth, kSuccess, OK)}},
9194 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9195 { TestRound(kConnect, kProxyChallenge, OK),
9196 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9197 &kGet, &kServerChallenge),
9198 TestRound(kGetAuth, kFailure, kAuthErr)}},
9199 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9200 { TestRound(kConnect, kProxyChallenge, OK),
9201 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9202 &kGet, &kServerChallenge),
9203 TestRound(kGetAuth, kSuccess, OK)}},
9204 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9205 { TestRound(kConnect, kProxyChallenge, OK),
9206 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9207 &kGet, &kServerChallenge),
9208 TestRound(kGetAuth, kFailure, kAuthErr)}},
9209 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9210 { TestRound(kConnect, kProxyChallenge, OK),
9211 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9212 &kGet, &kServerChallenge),
9213 TestRound(kGetAuth, kSuccess, OK)}},
9214 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9215 { TestRound(kConnect, kProxyChallenge, OK),
9216 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9217 &kGet, &kServerChallenge),
9218 TestRound(kGetAuth, kFailure, kAuthErr)}},
9219 };
9220
[email protected]044de0642010-06-17 10:42:159221 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089222 HttpAuthHandlerMock::Factory* auth_factory(
9223 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079224 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159225 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269226
9227 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159228 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089229 for (int n = 0; n < 2; n++) {
9230 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9231 std::string auth_challenge = "Mock realm=proxy";
9232 GURL origin(test_config.proxy_url);
9233 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9234 auth_challenge.end());
9235 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9236 origin, BoundNetLog());
9237 auth_handler->SetGenerateExpectation(
9238 test_config.proxy_auth_timing == AUTH_ASYNC,
9239 test_config.proxy_auth_rv);
9240 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9241 }
[email protected]044de0642010-06-17 10:42:159242 }
9243 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009244 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159245 std::string auth_challenge = "Mock realm=server";
9246 GURL origin(test_config.server_url);
9247 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9248 auth_challenge.end());
9249 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9250 origin, BoundNetLog());
9251 auth_handler->SetGenerateExpectation(
9252 test_config.server_auth_timing == AUTH_ASYNC,
9253 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089254 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159255 }
9256 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079257 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129258 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159259 } else {
[email protected]bb88e1d32013-05-03 23:11:079260 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159261 }
9262
9263 HttpRequestInfo request;
9264 request.method = "GET";
9265 request.url = GURL(test_config.server_url);
9266 request.load_flags = 0;
9267
[email protected]bb88e1d32013-05-03 23:11:079268 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159270
9271 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9272 const TestRound& read_write_round = test_config.rounds[round];
9273
9274 // Set up expected reads and writes.
9275 MockRead reads[2];
9276 reads[0] = read_write_round.read;
9277 size_t length_reads = 1;
9278 if (read_write_round.extra_read) {
9279 reads[1] = *read_write_round.extra_read;
9280 length_reads = 2;
9281 }
9282
9283 MockWrite writes[2];
9284 writes[0] = read_write_round.write;
9285 size_t length_writes = 1;
9286 if (read_write_round.extra_write) {
9287 writes[1] = *read_write_round.extra_write;
9288 length_writes = 2;
9289 }
9290 StaticSocketDataProvider data_provider(
9291 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079292 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159293
9294 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069295 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159296 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079297 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159298 &ssl_socket_data_provider);
9299
9300 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419301 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159302 int rv;
9303 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419304 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159305 } else {
[email protected]49639fa2011-12-20 23:22:419306 rv = trans.RestartWithAuth(
9307 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159308 }
9309 if (rv == ERR_IO_PENDING)
9310 rv = callback.WaitForResult();
9311
9312 // Compare results with expected data.
9313 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509314 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159315 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509316 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159317 } else {
9318 EXPECT_TRUE(response == NULL);
9319 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9320 continue;
9321 }
9322 if (round + 1 < test_config.num_auth_rounds) {
9323 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9324 } else {
9325 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9326 }
9327 }
[email protected]e5ae96a2010-04-14 20:12:459328 }
9329}
9330
[email protected]23e482282013-06-14 16:08:029331TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149332 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149333 HttpAuthHandlerMock::Factory* auth_factory(
9334 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079335 session_deps_.http_auth_handler_factory.reset(auth_factory);
9336 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9337 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9338 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149339
9340 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9341 auth_handler->set_connection_based(true);
9342 std::string auth_challenge = "Mock realm=server";
9343 GURL origin("http://www.example.com");
9344 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9345 auth_challenge.end());
9346 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9347 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089348 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149349
[email protected]c871bce92010-07-15 21:51:149350 int rv = OK;
9351 const HttpResponseInfo* response = NULL;
9352 HttpRequestInfo request;
9353 request.method = "GET";
9354 request.url = origin;
9355 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279356
[email protected]bb88e1d32013-05-03 23:11:079357 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109358
9359 // Use a TCP Socket Pool with only one connection per group. This is used
9360 // to validate that the TCP socket is not released to the pool between
9361 // each round of multi-round authentication.
9362 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289363 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9364 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109365 50, // Max sockets for pool
9366 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289367 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079368 session_deps_.host_resolver.get(),
9369 session_deps_.socket_factory.get(),
9370 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449371 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9372 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029373 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449374 session_peer.SetClientSocketPoolManager(
9375 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109376
[email protected]262eec82013-03-19 21:01:369377 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419379 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149380
9381 const MockWrite kGet(
9382 "GET / HTTP/1.1\r\n"
9383 "Host: www.example.com\r\n"
9384 "Connection: keep-alive\r\n\r\n");
9385 const MockWrite kGetAuth(
9386 "GET / HTTP/1.1\r\n"
9387 "Host: www.example.com\r\n"
9388 "Connection: keep-alive\r\n"
9389 "Authorization: auth_token\r\n\r\n");
9390
9391 const MockRead kServerChallenge(
9392 "HTTP/1.1 401 Unauthorized\r\n"
9393 "WWW-Authenticate: Mock realm=server\r\n"
9394 "Content-Type: text/html; charset=iso-8859-1\r\n"
9395 "Content-Length: 14\r\n\r\n"
9396 "Unauthorized\r\n");
9397 const MockRead kSuccess(
9398 "HTTP/1.1 200 OK\r\n"
9399 "Content-Type: text/html; charset=iso-8859-1\r\n"
9400 "Content-Length: 3\r\n\r\n"
9401 "Yes");
9402
9403 MockWrite writes[] = {
9404 // First round
9405 kGet,
9406 // Second round
9407 kGetAuth,
9408 // Third round
9409 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309410 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109411 kGetAuth,
9412 // Competing request
9413 kGet,
[email protected]c871bce92010-07-15 21:51:149414 };
9415 MockRead reads[] = {
9416 // First round
9417 kServerChallenge,
9418 // Second round
9419 kServerChallenge,
9420 // Third round
[email protected]eca50e122010-09-11 14:03:309421 kServerChallenge,
9422 // Fourth round
[email protected]c871bce92010-07-15 21:51:149423 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109424 // Competing response
9425 kSuccess,
[email protected]c871bce92010-07-15 21:51:149426 };
9427 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9428 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079429 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149430
[email protected]7ef4cbbb2011-02-06 11:19:109431 const char* const kSocketGroup = "www.example.com:80";
9432
9433 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149434 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419435 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149436 if (rv == ERR_IO_PENDING)
9437 rv = callback.WaitForResult();
9438 EXPECT_EQ(OK, rv);
9439 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509440 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149441 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289442 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149443
[email protected]7ef4cbbb2011-02-06 11:19:109444 // In between rounds, another request comes in for the same domain.
9445 // It should not be able to grab the TCP socket that trans has already
9446 // claimed.
9447 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509448 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419449 TestCompletionCallback callback_compete;
9450 rv = trans_compete->Start(
9451 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109452 EXPECT_EQ(ERR_IO_PENDING, rv);
9453 // callback_compete.WaitForResult at this point would stall forever,
9454 // since the HttpNetworkTransaction does not release the request back to
9455 // the pool until after authentication completes.
9456
9457 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149458 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419459 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149460 if (rv == ERR_IO_PENDING)
9461 rv = callback.WaitForResult();
9462 EXPECT_EQ(OK, rv);
9463 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509464 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149465 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289466 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149467
[email protected]7ef4cbbb2011-02-06 11:19:109468 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149469 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419470 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149471 if (rv == ERR_IO_PENDING)
9472 rv = callback.WaitForResult();
9473 EXPECT_EQ(OK, rv);
9474 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509475 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149476 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289477 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309478
[email protected]7ef4cbbb2011-02-06 11:19:109479 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309480 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419481 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309482 if (rv == ERR_IO_PENDING)
9483 rv = callback.WaitForResult();
9484 EXPECT_EQ(OK, rv);
9485 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509486 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309487 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289488 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109489
9490 // Read the body since the fourth round was successful. This will also
9491 // release the socket back to the pool.
9492 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509493 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109494 if (rv == ERR_IO_PENDING)
9495 rv = callback.WaitForResult();
9496 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509497 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109498 EXPECT_EQ(0, rv);
9499 // There are still 0 idle sockets, since the trans_compete transaction
9500 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289501 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109502
9503 // The competing request can now finish. Wait for the headers and then
9504 // read the body.
9505 rv = callback_compete.WaitForResult();
9506 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509507 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109508 if (rv == ERR_IO_PENDING)
9509 rv = callback.WaitForResult();
9510 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509511 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109512 EXPECT_EQ(0, rv);
9513
9514 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289515 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149516}
9517
[email protected]65041fa2010-05-21 06:56:539518// This tests the case that a request is issued via http instead of spdy after
9519// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029520TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389521 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169522 std::vector<NextProto> next_protos;
9523 next_protos.push_back(kProtoHTTP11);
9524 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539525 HttpRequestInfo request;
9526 request.method = "GET";
9527 request.url = GURL("https://www.google.com/");
9528 request.load_flags = 0;
9529
9530 MockWrite data_writes[] = {
9531 MockWrite("GET / HTTP/1.1\r\n"
9532 "Host: www.google.com\r\n"
9533 "Connection: keep-alive\r\n\r\n"),
9534 };
9535
[email protected]8a0fc822013-06-27 20:52:439536 std::string alternate_protocol_http_header =
9537 GetAlternateProtocolHttpHeader();
9538
[email protected]65041fa2010-05-21 06:56:539539 MockRead data_reads[] = {
9540 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439541 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539542 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069543 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539544 };
9545
[email protected]8ddf8322012-02-23 18:08:069546 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539547 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9548 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469549 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539550
[email protected]bb88e1d32013-05-03 23:11:079551 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539552
9553 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9554 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079555 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539556
[email protected]49639fa2011-12-20 23:22:419557 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539558
[email protected]bb88e1d32013-05-03 23:11:079559 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369560 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509561 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539562
[email protected]49639fa2011-12-20 23:22:419563 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539564
9565 EXPECT_EQ(ERR_IO_PENDING, rv);
9566 EXPECT_EQ(OK, callback.WaitForResult());
9567
9568 const HttpResponseInfo* response = trans->GetResponseInfo();
9569 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509570 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539571 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9572
9573 std::string response_data;
9574 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9575 EXPECT_EQ("hello world", response_data);
9576
9577 EXPECT_FALSE(response->was_fetched_via_spdy);
9578 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539579}
[email protected]26ef6582010-06-24 02:30:479580
[email protected]23e482282013-06-14 16:08:029581TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479582 // Simulate the SSL handshake completing with an NPN negotiation
9583 // followed by an immediate server closing of the socket.
9584 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389585 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039586 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479587
9588 HttpRequestInfo request;
9589 request.method = "GET";
9590 request.url = GURL("https://www.google.com/");
9591 request.load_flags = 0;
9592
[email protected]8ddf8322012-02-23 18:08:069593 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029594 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479596
[email protected]cdf8f7e72013-05-23 10:56:469597 scoped_ptr<SpdyFrame> req(
9598 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139599 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479600
9601 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069602 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479603 };
9604
[email protected]dd54bd82012-07-19 23:44:579605 DelayedSocketData spdy_data(
9606 0, // don't wait in this case, immediate hangup.
9607 spdy_reads, arraysize(spdy_reads),
9608 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079609 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479610
[email protected]49639fa2011-12-20 23:22:419611 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479612
[email protected]bb88e1d32013-05-03 23:11:079613 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369614 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479616
[email protected]49639fa2011-12-20 23:22:419617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479618 EXPECT_EQ(ERR_IO_PENDING, rv);
9619 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479620}
[email protected]65d34382010-07-01 18:12:269621
[email protected]795cbf82013-07-22 09:37:279622// A subclass of HttpAuthHandlerMock that records the request URL when
9623// it gets it. This is needed since the auth handler may get destroyed
9624// before we get a chance to query it.
9625class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9626 public:
9627 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9628
9629 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9630
9631 protected:
9632 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9633 const HttpRequestInfo* request,
9634 const CompletionCallback& callback,
9635 std::string* auth_token) OVERRIDE {
9636 *url_ = request->url;
9637 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9638 credentials, request, callback, auth_token);
9639 }
9640
9641 private:
9642 GURL* url_;
9643};
9644
[email protected]23e482282013-06-14 16:08:029645TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309646 // This test ensures that the URL passed into the proxy is upgraded
9647 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389648 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439649 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309650
[email protected]bb88e1d32013-05-03 23:11:079651 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209652 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9653 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079654 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279655 GURL request_url;
9656 {
9657 HttpAuthHandlerMock::Factory* auth_factory =
9658 new HttpAuthHandlerMock::Factory();
9659 UrlRecordingHttpAuthHandlerMock* auth_handler =
9660 new UrlRecordingHttpAuthHandlerMock(&request_url);
9661 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9662 auth_factory->set_do_init_from_challenge(true);
9663 session_deps_.http_auth_handler_factory.reset(auth_factory);
9664 }
[email protected]f45c1ee2010-08-03 00:54:309665
9666 HttpRequestInfo request;
9667 request.method = "GET";
9668 request.url = GURL("http://www.google.com");
9669 request.load_flags = 0;
9670
9671 // First round goes unauthenticated through the proxy.
9672 MockWrite data_writes_1[] = {
9673 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9674 "Host: www.google.com\r\n"
9675 "Proxy-Connection: keep-alive\r\n"
9676 "\r\n"),
9677 };
9678 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069679 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309680 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239681 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309682 "Proxy-Connection: close\r\n"
9683 "\r\n"),
9684 };
9685 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9686 data_writes_1, arraysize(data_writes_1));
9687
9688 // Second round tries to tunnel to www.google.com due to the
9689 // Alternate-Protocol announcement in the first round. It fails due
9690 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599691 // After the failure, a tunnel is established to www.google.com using
9692 // Proxy-Authorization headers. There is then a SPDY request round.
9693 //
[email protected]fe3b7dc2012-02-03 19:52:099694 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9695 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9696 // does a Disconnect and Connect on the same socket, rather than trying
9697 // to obtain a new one.
9698 //
[email protected]394816e92010-08-03 07:38:599699 // NOTE: Originally, the proxy response to the second CONNECT request
9700 // simply returned another 407 so the unit test could skip the SSL connection
9701 // establishment and SPDY framing issues. Alas, the
9702 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309703 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599704
[email protected]cdf8f7e72013-05-23 10:56:469705 scoped_ptr<SpdyFrame> req(
9706 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029707 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9708 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309709
[email protected]394816e92010-08-03 07:38:599710 MockWrite data_writes_2[] = {
9711 // First connection attempt without Proxy-Authorization.
9712 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9713 "Host: www.google.com\r\n"
9714 "Proxy-Connection: keep-alive\r\n"
9715 "\r\n"),
9716
9717 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309718 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9719 "Host: www.google.com\r\n"
9720 "Proxy-Connection: keep-alive\r\n"
9721 "Proxy-Authorization: auth_token\r\n"
9722 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309723
[email protected]394816e92010-08-03 07:38:599724 // SPDY request
9725 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309726 };
[email protected]394816e92010-08-03 07:38:599727 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9728 "Proxy-Authenticate: Mock\r\n"
9729 "Proxy-Connection: close\r\n"
9730 "\r\n");
9731 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9732 MockRead data_reads_2[] = {
9733 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069734 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9735 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599736 arraysize(kRejectConnectResponse) - 1, 1),
9737
9738 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069739 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:099740 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:599741
9742 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:099743 CreateMockRead(*resp.get(), 6),
9744 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:069745 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:599746 };
[email protected]dd54bd82012-07-19 23:44:579747 OrderedSocketData data_2(
9748 data_reads_2, arraysize(data_reads_2),
9749 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:309750
[email protected]8ddf8322012-02-23 18:08:069751 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029752 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:309753
[email protected]d973e99a2012-02-17 21:02:369754 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559755 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9756 NULL, 0, NULL, 0);
9757 hanging_non_alternate_protocol_socket.set_connect_data(
9758 never_finishing_connect);
9759
[email protected]bb88e1d32013-05-03 23:11:079760 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9761 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9763 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559764 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:079765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:309766
9767 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:419768 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:369769 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:509770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419771 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309772 EXPECT_EQ(ERR_IO_PENDING, rv);
9773 EXPECT_EQ(OK, callback_1.WaitForResult());
9774
9775 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:419776 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:369777 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:509778 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419779 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309780 EXPECT_EQ(ERR_IO_PENDING, rv);
9781 EXPECT_EQ(OK, callback_2.WaitForResult());
9782 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509783 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:309784 ASSERT_FALSE(response->auth_challenge.get() == NULL);
9785
9786 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:419787 TestCompletionCallback callback_3;
9788 rv = trans_2->RestartWithAuth(
9789 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:309790 EXPECT_EQ(ERR_IO_PENDING, rv);
9791 EXPECT_EQ(OK, callback_3.WaitForResult());
9792
9793 // After all that work, these two lines (or actually, just the scheme) are
9794 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:309795 EXPECT_EQ("https", request_url.scheme());
9796 EXPECT_EQ("www.google.com", request_url.host());
9797
[email protected]029c83b62013-01-24 05:28:209798 LoadTimingInfo load_timing_info;
9799 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9800 TestLoadTimingNotReusedWithPac(load_timing_info,
9801 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:389802}
9803
9804// Test that if we cancel the transaction as the connection is completing, that
9805// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:029806TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:389807 // Setup everything about the connection to complete synchronously, so that
9808 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9809 // for is the callback from the HttpStreamRequest.
9810 // Then cancel the transaction.
9811 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:369812 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:389813 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069814 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9815 MockRead(SYNCHRONOUS, "hello world"),
9816 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:389817 };
9818
[email protected]8e6441ca2010-08-19 05:56:389819 HttpRequestInfo request;
9820 request.method = "GET";
9821 request.url = GURL("http://www.google.com/");
9822 request.load_flags = 0;
9823
[email protected]bb88e1d32013-05-03 23:11:079824 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:079825 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:279826 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:079827 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:279828
[email protected]8e6441ca2010-08-19 05:56:389829 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9830 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079831 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:389832
[email protected]49639fa2011-12-20 23:22:419833 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:389834
[email protected]333bdf62012-06-08 22:57:299835 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:419836 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:389837 EXPECT_EQ(ERR_IO_PENDING, rv);
9838 trans.reset(); // Cancel the transaction here.
9839
[email protected]2da659e2013-05-23 20:51:349840 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:309841}
9842
[email protected]76a505b2010-08-25 06:23:009843// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029844TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:079845 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209846 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299847 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079848 session_deps_.net_log = log.bound().net_log();
9849 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009850
[email protected]76a505b2010-08-25 06:23:009851 HttpRequestInfo request;
9852 request.method = "GET";
9853 request.url = GURL("http://www.google.com/");
9854
9855 MockWrite data_writes1[] = {
9856 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9857 "Host: www.google.com\r\n"
9858 "Proxy-Connection: keep-alive\r\n\r\n"),
9859 };
9860
9861 MockRead data_reads1[] = {
9862 MockRead("HTTP/1.1 200 OK\r\n"),
9863 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9864 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069865 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009866 };
9867
9868 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9869 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079870 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:009871
[email protected]49639fa2011-12-20 23:22:419872 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009873
[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]0b0bf032010-09-21 18:08:509876
[email protected]49639fa2011-12-20 23:22:419877 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009878 EXPECT_EQ(ERR_IO_PENDING, rv);
9879
9880 rv = callback1.WaitForResult();
9881 EXPECT_EQ(OK, rv);
9882
9883 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509884 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009885
9886 EXPECT_TRUE(response->headers->IsKeepAlive());
9887 EXPECT_EQ(200, response->headers->response_code());
9888 EXPECT_EQ(100, response->headers->GetContentLength());
9889 EXPECT_TRUE(response->was_fetched_via_proxy);
9890 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209891
9892 LoadTimingInfo load_timing_info;
9893 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9894 TestLoadTimingNotReusedWithPac(load_timing_info,
9895 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:009896}
9897
9898// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029899TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:079900 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209901 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299902 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079903 session_deps_.net_log = log.bound().net_log();
9904 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009905
[email protected]76a505b2010-08-25 06:23:009906 HttpRequestInfo request;
9907 request.method = "GET";
9908 request.url = GURL("https://www.google.com/");
9909
9910 // Since we have proxy, should try to establish tunnel.
9911 MockWrite data_writes1[] = {
9912 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9913 "Host: www.google.com\r\n"
9914 "Proxy-Connection: keep-alive\r\n\r\n"),
9915
9916 MockWrite("GET / HTTP/1.1\r\n"
9917 "Host: www.google.com\r\n"
9918 "Connection: keep-alive\r\n\r\n"),
9919 };
9920
9921 MockRead data_reads1[] = {
9922 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
9923
9924 MockRead("HTTP/1.1 200 OK\r\n"),
9925 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9926 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069927 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009928 };
9929
9930 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9931 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069933 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009935
[email protected]49639fa2011-12-20 23:22:419936 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009937
[email protected]262eec82013-03-19 21:01:369938 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509939 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509940
[email protected]49639fa2011-12-20 23:22:419941 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009942 EXPECT_EQ(ERR_IO_PENDING, rv);
9943
9944 rv = callback1.WaitForResult();
9945 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:579946 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409947 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009948 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409949 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009950 NetLog::PHASE_NONE);
9951 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409952 entries, pos,
[email protected]76a505b2010-08-25 06:23:009953 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9954 NetLog::PHASE_NONE);
9955
9956 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509957 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009958
9959 EXPECT_TRUE(response->headers->IsKeepAlive());
9960 EXPECT_EQ(200, response->headers->response_code());
9961 EXPECT_EQ(100, response->headers->GetContentLength());
9962 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9963 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:209964
9965 LoadTimingInfo load_timing_info;
9966 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9967 TestLoadTimingNotReusedWithPac(load_timing_info,
9968 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:009969}
9970
9971// Test a basic HTTPS GET request through a proxy, but the server hangs up
9972// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:029973TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:079974 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299975 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079976 session_deps_.net_log = log.bound().net_log();
9977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009978
[email protected]76a505b2010-08-25 06:23:009979 HttpRequestInfo request;
9980 request.method = "GET";
9981 request.url = GURL("https://www.google.com/");
9982
9983 // Since we have proxy, should try to establish tunnel.
9984 MockWrite data_writes1[] = {
9985 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9986 "Host: www.google.com\r\n"
9987 "Proxy-Connection: keep-alive\r\n\r\n"),
9988
9989 MockWrite("GET / HTTP/1.1\r\n"
9990 "Host: www.google.com\r\n"
9991 "Connection: keep-alive\r\n\r\n"),
9992 };
9993
9994 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:069995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:009996 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069997 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:009998 };
9999
10000 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10001 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710002 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610003 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710004 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010005
[email protected]49639fa2011-12-20 23:22:4110006 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010007
[email protected]262eec82013-03-19 21:01:3610008 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010009 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010010
[email protected]49639fa2011-12-20 23:22:4110011 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010012 EXPECT_EQ(ERR_IO_PENDING, rv);
10013
10014 rv = callback1.WaitForResult();
10015 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710016 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010017 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010018 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010019 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010020 NetLog::PHASE_NONE);
10021 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010022 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010023 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10024 NetLog::PHASE_NONE);
10025}
10026
[email protected]749eefa82010-09-13 22:14:0310027// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210028TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610029 scoped_ptr<SpdyFrame> req(
10030 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310031 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10032
[email protected]23e482282013-06-14 16:08:0210033 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10034 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310035 MockRead spdy_reads[] = {
10036 CreateMockRead(*resp),
10037 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610038 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310039 };
10040
[email protected]dd54bd82012-07-19 23:44:5710041 DelayedSocketData spdy_data(
10042 1, // wait for one write to finish before reading.
10043 spdy_reads, arraysize(spdy_reads),
10044 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710045 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310046
[email protected]8ddf8322012-02-23 18:08:0610047 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210048 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310050
[email protected]bb88e1d32013-05-03 23:11:0710051 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310052
10053 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810054 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010055 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10056 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:2710057 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610058 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310059
10060 HttpRequestInfo request;
10061 request.method = "GET";
10062 request.url = GURL("https://www.google.com/");
10063 request.load_flags = 0;
10064
10065 // This is the important line that marks this as a preconnect.
10066 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10067
[email protected]262eec82013-03-19 21:01:3610068 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310070
[email protected]41d64e82013-07-03 22:44:2610071 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110072 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310073 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110074 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310075}
10076
[email protected]73b8dd222010-11-11 19:55:2410077// Given a net error, cause that error to be returned from the first Write()
10078// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210079void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710080 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710081 net::HttpRequestInfo request_info;
10082 request_info.url = GURL("https://www.example.com/");
10083 request_info.method = "GET";
10084 request_info.load_flags = net::LOAD_NORMAL;
10085
[email protected]8ddf8322012-02-23 18:08:0610086 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410087 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610088 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410089 };
10090 net::StaticSocketDataProvider data(NULL, 0,
10091 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710092 session_deps_.socket_factory->AddSocketDataProvider(&data);
10093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410094
[email protected]bb88e1d32013-05-03 23:11:0710095 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610096 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410098
[email protected]49639fa2011-12-20 23:22:4110099 TestCompletionCallback callback;
10100 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410101 if (rv == net::ERR_IO_PENDING)
10102 rv = callback.WaitForResult();
10103 ASSERT_EQ(error, rv);
10104}
10105
[email protected]23e482282013-06-14 16:08:0210106TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410107 // Just check a grab bag of cert errors.
10108 static const int kErrors[] = {
10109 ERR_CERT_COMMON_NAME_INVALID,
10110 ERR_CERT_AUTHORITY_INVALID,
10111 ERR_CERT_DATE_INVALID,
10112 };
10113 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610114 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10115 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410116 }
10117}
10118
[email protected]bd0b6772011-01-11 19:59:3010119// Ensure that a client certificate is removed from the SSL client auth
10120// cache when:
10121// 1) No proxy is involved.
10122// 2) TLS False Start is disabled.
10123// 3) The initial TLS handshake requests a client certificate.
10124// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210125TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310126 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710127 net::HttpRequestInfo request_info;
10128 request_info.url = GURL("https://www.example.com/");
10129 request_info.method = "GET";
10130 request_info.load_flags = net::LOAD_NORMAL;
10131
[email protected]bd0b6772011-01-11 19:59:3010132 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10133 cert_request->host_and_port = "www.example.com:443";
10134
10135 // [ssl_]data1 contains the data for the first SSL handshake. When a
10136 // CertificateRequest is received for the first time, the handshake will
10137 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610138 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010139 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710140 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010141 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710142 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010143
10144 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10145 // False Start is not being used, the result of the SSL handshake will be
10146 // returned as part of the SSLClientSocket::Connect() call. This test
10147 // matches the result of a server sending a handshake_failure alert,
10148 // rather than a Finished message, because it requires a client
10149 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610150 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010151 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010153 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710154 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010155
10156 // [ssl_]data3 contains the data for the third SSL handshake. When a
10157 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710158 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10159 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010160 // of the HttpNetworkTransaction. Because this test failure is due to
10161 // requiring a client certificate, this fallback handshake should also
10162 // fail.
[email protected]8ddf8322012-02-23 18:08:0610163 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010164 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010166 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710167 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010168
[email protected]80c75f682012-05-26 16:22:1710169 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10170 // connection to a server fails during an SSL handshake,
10171 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10172 // connection was attempted with TLSv1. This is transparent to the caller
10173 // of the HttpNetworkTransaction. Because this test failure is due to
10174 // requiring a client certificate, this fallback handshake should also
10175 // fail.
10176 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10177 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710179 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710180 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710181
[email protected]7799de12013-05-30 05:52:5110182 // Need one more if TLSv1.2 is enabled.
10183 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10184 ssl_data5.cert_request_info = cert_request.get();
10185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10186 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10187 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10188
[email protected]bb88e1d32013-05-03 23:11:0710189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610190 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010192
[email protected]bd0b6772011-01-11 19:59:3010193 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110194 TestCompletionCallback callback;
10195 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010196 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10197
10198 // Complete the SSL handshake, which should abort due to requiring a
10199 // client certificate.
10200 rv = callback.WaitForResult();
10201 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10202
10203 // Indicate that no certificate should be supplied. From the perspective
10204 // of SSLClientCertCache, NULL is just as meaningful as a real
10205 // certificate, so this is the same as supply a
10206 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110207 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010208 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10209
10210 // Ensure the certificate was added to the client auth cache before
10211 // allowing the connection to continue restarting.
10212 scoped_refptr<X509Certificate> client_cert;
10213 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10214 &client_cert));
10215 ASSERT_EQ(NULL, client_cert.get());
10216
10217 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710218 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10219 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010220 rv = callback.WaitForResult();
10221 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10222
10223 // Ensure that the client certificate is removed from the cache on a
10224 // handshake failure.
10225 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10226 &client_cert));
10227}
10228
10229// Ensure that a client certificate is removed from the SSL client auth
10230// cache when:
10231// 1) No proxy is involved.
10232// 2) TLS False Start is enabled.
10233// 3) The initial TLS handshake requests a client certificate.
10234// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210235TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310236 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710237 net::HttpRequestInfo request_info;
10238 request_info.url = GURL("https://www.example.com/");
10239 request_info.method = "GET";
10240 request_info.load_flags = net::LOAD_NORMAL;
10241
[email protected]bd0b6772011-01-11 19:59:3010242 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10243 cert_request->host_and_port = "www.example.com:443";
10244
10245 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10246 // return successfully after reading up to the peer's Certificate message.
10247 // This is to allow the caller to call SSLClientSocket::Write(), which can
10248 // enqueue application data to be sent in the same packet as the
10249 // ChangeCipherSpec and Finished messages.
10250 // The actual handshake will be finished when SSLClientSocket::Read() is
10251 // called, which expects to process the peer's ChangeCipherSpec and
10252 // Finished messages. If there was an error negotiating with the peer,
10253 // such as due to the peer requiring a client certificate when none was
10254 // supplied, the alert sent by the peer won't be processed until Read() is
10255 // called.
10256
10257 // Like the non-False Start case, when a client certificate is requested by
10258 // the peer, the handshake is aborted during the Connect() call.
10259 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610260 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010261 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710262 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010263 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710264 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010265
10266 // When a client certificate is supplied, Connect() will not be aborted
10267 // when the peer requests the certificate. Instead, the handshake will
10268 // artificially succeed, allowing the caller to write the HTTP request to
10269 // the socket. The handshake messages are not processed until Read() is
10270 // called, which then detects that the handshake was aborted, due to the
10271 // peer sending a handshake_failure because it requires a client
10272 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610273 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010274 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010276 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610277 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010278 };
10279 net::StaticSocketDataProvider data2(
10280 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710281 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010282
10283 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710284 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10285 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610286 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010287 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010289 net::StaticSocketDataProvider data3(
10290 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710291 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010292
[email protected]80c75f682012-05-26 16:22:1710293 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10294 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10295 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10296 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710297 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710298 net::StaticSocketDataProvider data4(
10299 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710300 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710301
[email protected]7799de12013-05-30 05:52:5110302 // Need one more if TLSv1.2 is enabled.
10303 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10304 ssl_data5.cert_request_info = cert_request.get();
10305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10306 net::StaticSocketDataProvider data5(
10307 data2_reads, arraysize(data2_reads), NULL, 0);
10308 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10309
[email protected]bb88e1d32013-05-03 23:11:0710310 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610311 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010312 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010313
[email protected]bd0b6772011-01-11 19:59:3010314 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110315 TestCompletionCallback callback;
10316 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010317 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10318
10319 // Complete the SSL handshake, which should abort due to requiring a
10320 // client certificate.
10321 rv = callback.WaitForResult();
10322 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10323
10324 // Indicate that no certificate should be supplied. From the perspective
10325 // of SSLClientCertCache, NULL is just as meaningful as a real
10326 // certificate, so this is the same as supply a
10327 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110328 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010329 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10330
10331 // Ensure the certificate was added to the client auth cache before
10332 // allowing the connection to continue restarting.
10333 scoped_refptr<X509Certificate> client_cert;
10334 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10335 &client_cert));
10336 ASSERT_EQ(NULL, client_cert.get());
10337
[email protected]bd0b6772011-01-11 19:59:3010338 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710339 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10340 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010341 rv = callback.WaitForResult();
10342 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10343
10344 // Ensure that the client certificate is removed from the cache on a
10345 // handshake failure.
10346 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10347 &client_cert));
10348}
10349
[email protected]8c405132011-01-11 22:03:1810350// Ensure that a client certificate is removed from the SSL client auth
10351// cache when:
10352// 1) An HTTPS proxy is involved.
10353// 3) The HTTPS proxy requests a client certificate.
10354// 4) The client supplies an invalid/unacceptable certificate for the
10355// proxy.
10356// The test is repeated twice, first for connecting to an HTTPS endpoint,
10357// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210358TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710359 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810360 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910361 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710362 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810363
10364 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10365 cert_request->host_and_port = "proxy:70";
10366
10367 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10368 // [ssl_]data[1-3]. Rather than represending the endpoint
10369 // (www.example.com:443), they represent failures with the HTTPS proxy
10370 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610371 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810372 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810374 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710375 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810376
[email protected]8ddf8322012-02-23 18:08:0610377 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810378 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810380 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710381 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810382
[email protected]80c75f682012-05-26 16:22:1710383 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10384#if 0
[email protected]8ddf8322012-02-23 18:08:0610385 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810386 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810388 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710389 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710390#endif
[email protected]8c405132011-01-11 22:03:1810391
10392 net::HttpRequestInfo requests[2];
10393 requests[0].url = GURL("https://www.example.com/");
10394 requests[0].method = "GET";
10395 requests[0].load_flags = net::LOAD_NORMAL;
10396
10397 requests[1].url = GURL("http://www.example.com/");
10398 requests[1].method = "GET";
10399 requests[1].load_flags = net::LOAD_NORMAL;
10400
10401 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710402 session_deps_.socket_factory->ResetNextMockIndexes();
10403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810404 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810406
10407 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110408 TestCompletionCallback callback;
10409 int rv = trans->Start(
10410 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810411 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10412
10413 // Complete the SSL handshake, which should abort due to requiring a
10414 // client certificate.
10415 rv = callback.WaitForResult();
10416 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10417
10418 // Indicate that no certificate should be supplied. From the perspective
10419 // of SSLClientCertCache, NULL is just as meaningful as a real
10420 // certificate, so this is the same as supply a
10421 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110422 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810423 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10424
10425 // Ensure the certificate was added to the client auth cache before
10426 // allowing the connection to continue restarting.
10427 scoped_refptr<X509Certificate> client_cert;
10428 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10429 &client_cert));
10430 ASSERT_EQ(NULL, client_cert.get());
10431 // Ensure the certificate was NOT cached for the endpoint. This only
10432 // applies to HTTPS requests, but is fine to check for HTTP requests.
10433 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10434 &client_cert));
10435
10436 // Restart the handshake. This will consume ssl_data2, which fails, and
10437 // then consume ssl_data3, which should also fail. The result code is
10438 // checked against what ssl_data3 should return.
10439 rv = callback.WaitForResult();
10440 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10441
10442 // Now that the new handshake has failed, ensure that the client
10443 // certificate was removed from the client auth cache.
10444 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10445 &client_cert));
10446 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10447 &client_cert));
10448 }
10449}
10450
[email protected]23e482282013-06-14 16:08:0210451// Unlike TEST/TEST_F, which are macros that expand to further macros,
10452// TEST_P is a macro that expands directly to code that stringizes the
10453// arguments. As a result, macros passed as parameters (such as prefix
10454// or test_case_name) will not be expanded by the preprocessor. To
10455// work around this, indirect the macro for TEST_P, so that the
10456// pre-processor will expand macros such as MAYBE_test_name before
10457// instantiating the test.
10458#define WRAPPED_TEST_P(test_case_name, test_name) \
10459 TEST_P(test_case_name, test_name)
10460
[email protected]45b170822012-05-04 21:18:1410461// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10462#if defined(OS_WIN)
10463#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10464#else
10465#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10466#endif
[email protected]23e482282013-06-14 16:08:0210467WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610468 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310469 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610470
10471 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710472 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610474 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10475 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610476
[email protected]8ddf8322012-02-23 18:08:0610477 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210478 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710479 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610480
[email protected]cdf8f7e72013-05-23 10:56:4610481 scoped_ptr<SpdyFrame> host1_req(
10482 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10483 scoped_ptr<SpdyFrame> host2_req(
10484 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610485 MockWrite spdy_writes[] = {
10486 CreateMockWrite(*host1_req, 1),
10487 CreateMockWrite(*host2_req, 4),
10488 };
[email protected]23e482282013-06-14 16:08:0210489 scoped_ptr<SpdyFrame> host1_resp(
10490 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10491 scoped_ptr<SpdyFrame> host1_resp_body(
10492 spdy_util_.ConstructSpdyBodyFrame(1, true));
10493 scoped_ptr<SpdyFrame> host2_resp(
10494 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10495 scoped_ptr<SpdyFrame> host2_resp_body(
10496 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610497 MockRead spdy_reads[] = {
10498 CreateMockRead(*host1_resp, 2),
10499 CreateMockRead(*host1_resp_body, 3),
10500 CreateMockRead(*host2_resp, 5),
10501 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610502 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610503 };
10504
[email protected]d2b5f092012-06-08 23:55:0210505 IPAddressNumber ip;
10506 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10507 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10508 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710509 OrderedSocketData spdy_data(
10510 connect,
10511 spdy_reads, arraysize(spdy_reads),
10512 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710513 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610514
[email protected]aa22b242011-11-16 18:58:2910515 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610516 HttpRequestInfo request1;
10517 request1.method = "GET";
10518 request1.url = GURL("https://www.google.com/");
10519 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010520 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610521
[email protected]49639fa2011-12-20 23:22:4110522 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610523 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110524 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610525
10526 const HttpResponseInfo* response = trans1.GetResponseInfo();
10527 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010528 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610529 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10530
10531 std::string response_data;
10532 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10533 EXPECT_EQ("hello!", response_data);
10534
10535 // Preload www.gmail.com into HostCache.
10536 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010537 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610538 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010539 rv = session_deps_.host_resolver->Resolve(resolve_info,
10540 DEFAULT_PRIORITY,
10541 &ignored,
10542 callback.callback(),
10543 NULL,
10544 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710545 EXPECT_EQ(ERR_IO_PENDING, rv);
10546 rv = callback.WaitForResult();
10547 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610548
10549 HttpRequestInfo request2;
10550 request2.method = "GET";
10551 request2.url = GURL("https://www.gmail.com/");
10552 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010553 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610554
[email protected]49639fa2011-12-20 23:22:4110555 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610556 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110557 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610558
10559 response = trans2.GetResponseInfo();
10560 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010561 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610562 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10563 EXPECT_TRUE(response->was_fetched_via_spdy);
10564 EXPECT_TRUE(response->was_npn_negotiated);
10565 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10566 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610567}
[email protected]45b170822012-05-04 21:18:1410568#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610569
[email protected]23e482282013-06-14 16:08:0210570TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210571 HttpStreamFactory::set_use_alternate_protocols(true);
10572 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10573
10574 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710575 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210577 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10578 pool_peer.DisableDomainAuthenticationVerification();
10579
10580 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210581 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210583
[email protected]cdf8f7e72013-05-23 10:56:4610584 scoped_ptr<SpdyFrame> host1_req(
10585 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10586 scoped_ptr<SpdyFrame> host2_req(
10587 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210588 MockWrite spdy_writes[] = {
10589 CreateMockWrite(*host1_req, 1),
10590 CreateMockWrite(*host2_req, 4),
10591 };
[email protected]23e482282013-06-14 16:08:0210592 scoped_ptr<SpdyFrame> host1_resp(
10593 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10594 scoped_ptr<SpdyFrame> host1_resp_body(
10595 spdy_util_.ConstructSpdyBodyFrame(1, true));
10596 scoped_ptr<SpdyFrame> host2_resp(
10597 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10598 scoped_ptr<SpdyFrame> host2_resp_body(
10599 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210600 MockRead spdy_reads[] = {
10601 CreateMockRead(*host1_resp, 2),
10602 CreateMockRead(*host1_resp_body, 3),
10603 CreateMockRead(*host2_resp, 5),
10604 CreateMockRead(*host2_resp_body, 6),
10605 MockRead(ASYNC, 0, 7),
10606 };
10607
10608 IPAddressNumber ip;
10609 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10610 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10611 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710612 OrderedSocketData spdy_data(
10613 connect,
10614 spdy_reads, arraysize(spdy_reads),
10615 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710616 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210617
10618 TestCompletionCallback callback;
10619 HttpRequestInfo request1;
10620 request1.method = "GET";
10621 request1.url = GURL("https://www.google.com/");
10622 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010623 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210624
10625 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10626 EXPECT_EQ(ERR_IO_PENDING, rv);
10627 EXPECT_EQ(OK, callback.WaitForResult());
10628
10629 const HttpResponseInfo* response = trans1.GetResponseInfo();
10630 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010631 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210632 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10633
10634 std::string response_data;
10635 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10636 EXPECT_EQ("hello!", response_data);
10637
10638 HttpRequestInfo request2;
10639 request2.method = "GET";
10640 request2.url = GURL("https://www.gmail.com/");
10641 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010642 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210643
10644 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10645 EXPECT_EQ(ERR_IO_PENDING, rv);
10646 EXPECT_EQ(OK, callback.WaitForResult());
10647
10648 response = trans2.GetResponseInfo();
10649 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010650 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210651 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10652 EXPECT_TRUE(response->was_fetched_via_spdy);
10653 EXPECT_TRUE(response->was_npn_negotiated);
10654 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10655 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210656}
10657
[email protected]e3ceb682011-06-28 23:55:4610658class OneTimeCachingHostResolver : public net::HostResolver {
10659 public:
10660 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10661 : host_port_(host_port) {}
10662 virtual ~OneTimeCachingHostResolver() {}
10663
10664 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10665
10666 // HostResolver methods:
10667 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010668 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610669 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910670 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610671 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010672 const BoundNetLog& net_log) OVERRIDE {
10673 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010674 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010675 }
10676
10677 virtual int ResolveFromCache(const RequestInfo& info,
10678 AddressList* addresses,
10679 const BoundNetLog& net_log) OVERRIDE {
10680 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10681 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910682 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610683 return rv;
10684 }
10685
[email protected]95a214c2011-08-04 21:50:4010686 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610687 host_resolver_.CancelRequest(req);
10688 }
10689
[email protected]46da33be2011-07-19 21:58:0410690 MockCachingHostResolver* GetMockHostResolver() {
10691 return &host_resolver_;
10692 }
10693
[email protected]e3ceb682011-06-28 23:55:4610694 private:
10695 MockCachingHostResolver host_resolver_;
10696 const HostPortPair host_port_;
10697};
10698
[email protected]45b170822012-05-04 21:18:1410699// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10700#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710701#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10702 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410703#else
[email protected]bb88e1d32013-05-03 23:11:0710704#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10705 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410706#endif
[email protected]23e482282013-06-14 16:08:0210707WRAPPED_TEST_P(HttpNetworkTransactionTest,
10708 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210709// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10710// prefix doesn't work with parametrized tests).
10711#if defined(OS_WIN)
10712 return;
10713#endif
10714
[email protected]e3ceb682011-06-28 23:55:4610715 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310716 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610717
10718 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610719 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410720 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710721 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610722 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710723 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610724 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10725 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610726
[email protected]8ddf8322012-02-23 18:08:0610727 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210728 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710729 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610730
[email protected]cdf8f7e72013-05-23 10:56:4610731 scoped_ptr<SpdyFrame> host1_req(
10732 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10733 scoped_ptr<SpdyFrame> host2_req(
10734 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610735 MockWrite spdy_writes[] = {
10736 CreateMockWrite(*host1_req, 1),
10737 CreateMockWrite(*host2_req, 4),
10738 };
[email protected]23e482282013-06-14 16:08:0210739 scoped_ptr<SpdyFrame> host1_resp(
10740 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10741 scoped_ptr<SpdyFrame> host1_resp_body(
10742 spdy_util_.ConstructSpdyBodyFrame(1, true));
10743 scoped_ptr<SpdyFrame> host2_resp(
10744 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10745 scoped_ptr<SpdyFrame> host2_resp_body(
10746 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610747 MockRead spdy_reads[] = {
10748 CreateMockRead(*host1_resp, 2),
10749 CreateMockRead(*host1_resp_body, 3),
10750 CreateMockRead(*host2_resp, 5),
10751 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610752 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610753 };
10754
[email protected]d2b5f092012-06-08 23:55:0210755 IPAddressNumber ip;
10756 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10757 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10758 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710759 OrderedSocketData spdy_data(
10760 connect,
10761 spdy_reads, arraysize(spdy_reads),
10762 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710763 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610764
[email protected]aa22b242011-11-16 18:58:2910765 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610766 HttpRequestInfo request1;
10767 request1.method = "GET";
10768 request1.url = GURL("https://www.google.com/");
10769 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010770 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610771
[email protected]49639fa2011-12-20 23:22:4110772 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610773 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110774 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610775
10776 const HttpResponseInfo* response = trans1.GetResponseInfo();
10777 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010778 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610779 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10780
10781 std::string response_data;
10782 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10783 EXPECT_EQ("hello!", response_data);
10784
10785 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1010786 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4610787 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010788 rv = host_resolver.Resolve(resolve_info,
10789 DEFAULT_PRIORITY,
10790 &ignored,
10791 callback.callback(),
10792 NULL,
10793 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710794 EXPECT_EQ(ERR_IO_PENDING, rv);
10795 rv = callback.WaitForResult();
10796 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610797
10798 HttpRequestInfo request2;
10799 request2.method = "GET";
10800 request2.url = GURL("https://www.gmail.com/");
10801 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010802 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610803
[email protected]49639fa2011-12-20 23:22:4110804 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610805 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110806 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610807
10808 response = trans2.GetResponseInfo();
10809 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010810 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610811 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10812 EXPECT_TRUE(response->was_fetched_via_spdy);
10813 EXPECT_TRUE(response->was_npn_negotiated);
10814 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10815 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610816}
[email protected]45b170822012-05-04 21:18:1410817#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4610818
[email protected]23e482282013-06-14 16:08:0210819TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910820 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610821 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910822 };
10823 MockRead data_reads2[] = {
10824 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10825 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610826 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910827 };
10828 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10829 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10830 StaticSocketDataProvider* data[] = { &data1, &data2 };
10831
10832 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10833
10834 EXPECT_EQ(OK, out.rv);
10835 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10836 EXPECT_EQ("hello world", out.response_data);
10837}
10838
[email protected]23e482282013-06-14 16:08:0210839TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910840 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0610841 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910842 };
10843 MockWrite data_writes2[] = {
10844 MockWrite("GET / HTTP/1.1\r\n"
10845 "Host: www.google.com\r\n"
10846 "Connection: keep-alive\r\n\r\n"),
10847 };
10848 MockRead data_reads2[] = {
10849 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10850 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610851 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910852 };
10853 StaticSocketDataProvider data1(NULL, 0,
10854 data_writes1, arraysize(data_writes1));
10855 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10856 data_writes2, arraysize(data_writes2));
10857 StaticSocketDataProvider* data[] = { &data1, &data2 };
10858
10859 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10860
10861 EXPECT_EQ(OK, out.rv);
10862 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10863 EXPECT_EQ("hello world", out.response_data);
10864}
10865
[email protected]23e482282013-06-14 16:08:0210866TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0410867 const std::string https_url = "https://www.google.com/";
10868 const std::string http_url = "http://www.google.com:443/";
10869
10870 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4610871 scoped_ptr<SpdyFrame> req1(
10872 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410873
10874 MockWrite writes1[] = {
10875 CreateMockWrite(*req1, 0),
10876 };
10877
[email protected]23e482282013-06-14 16:08:0210878 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10879 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0410880 MockRead reads1[] = {
10881 CreateMockRead(*resp1, 1),
10882 CreateMockRead(*body1, 2),
10883 MockRead(ASYNC, ERR_IO_PENDING, 3)
10884 };
10885
[email protected]dd54bd82012-07-19 23:44:5710886 DelayedSocketData data1(
10887 1, reads1, arraysize(reads1),
10888 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410889 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710890 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410891
10892 // HTTP GET for the HTTP URL
10893 MockWrite writes2[] = {
10894 MockWrite(ASYNC, 4,
10895 "GET / HTTP/1.1\r\n"
10896 "Host: www.google.com:443\r\n"
10897 "Connection: keep-alive\r\n\r\n"),
10898 };
10899
10900 MockRead reads2[] = {
10901 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10902 MockRead(ASYNC, 6, "hello"),
10903 MockRead(ASYNC, 7, OK),
10904 };
10905
[email protected]dd54bd82012-07-19 23:44:5710906 DelayedSocketData data2(
10907 1, reads2, arraysize(reads2),
10908 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0410909
[email protected]8450d722012-07-02 19:14:0410910 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210911 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710912 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10913 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10914 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0410915
[email protected]bb88e1d32013-05-03 23:11:0710916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410917
10918 // Start the first transaction to set up the SpdySession
10919 HttpRequestInfo request1;
10920 request1.method = "GET";
10921 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410922 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010923 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410924 TestCompletionCallback callback1;
10925 EXPECT_EQ(ERR_IO_PENDING,
10926 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410927 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410928
10929 EXPECT_EQ(OK, callback1.WaitForResult());
10930 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
10931
10932 // Now, start the HTTP request
10933 HttpRequestInfo request2;
10934 request2.method = "GET";
10935 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0410936 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010937 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0410938 TestCompletionCallback callback2;
10939 EXPECT_EQ(ERR_IO_PENDING,
10940 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410941 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410942
10943 EXPECT_EQ(OK, callback2.WaitForResult());
10944 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
10945}
10946
[email protected]23e482282013-06-14 16:08:0210947TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0410948 const std::string https_url = "https://www.google.com/";
10949 const std::string http_url = "http://www.google.com:443/";
10950
10951 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5410952 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
10953 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4610954 scoped_ptr<SpdyFrame> req1(
10955 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410956
10957 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0210958 scoped_ptr<SpdyFrame> wrapped_req1(
10959 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0410960 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0210961 spdy_util_.GetMethodKey(), "GET",
10962 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
10963 spdy_util_.GetHostKey(), "www.google.com:443",
10964 spdy_util_.GetSchemeKey(), "http",
10965 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0410966 };
[email protected]4bd46222013-05-14 19:32:2310967 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
10968 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
10969 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0410970
10971 MockWrite writes1[] = {
10972 CreateMockWrite(*connect, 0),
10973 CreateMockWrite(*wrapped_req1, 2),
10974 CreateMockWrite(*req2, 5),
10975 };
10976
[email protected]23e482282013-06-14 16:08:0210977 scoped_ptr<SpdyFrame> conn_resp(
10978 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10979 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10980 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10981 scoped_ptr<SpdyFrame> wrapped_resp1(
10982 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
10983 scoped_ptr<SpdyFrame> wrapped_body1(
10984 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
10985 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10986 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0410987 MockRead reads1[] = {
10988 CreateMockRead(*conn_resp, 1),
10989 CreateMockRead(*wrapped_resp1, 3),
10990 CreateMockRead(*wrapped_body1, 4),
10991 CreateMockRead(*resp2, 6),
10992 CreateMockRead(*body2, 7),
10993 MockRead(ASYNC, ERR_IO_PENDING, 8)
10994 };
10995
[email protected]dd54bd82012-07-19 23:44:5710996 DeterministicSocketData data1(reads1, arraysize(reads1),
10997 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410998 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710999 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411000
[email protected]bb88e1d32013-05-03 23:11:0711001 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211002 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11003 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711004 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411005 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211006 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711007 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411008 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211009 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711010 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11011 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411012
11013 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711014 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411015
11016 // Start the first transaction to set up the SpdySession
11017 HttpRequestInfo request1;
11018 request1.method = "GET";
11019 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411020 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011021 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411022 TestCompletionCallback callback1;
11023 EXPECT_EQ(ERR_IO_PENDING,
11024 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411025 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711026 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411027
11028 EXPECT_EQ(OK, callback1.WaitForResult());
11029 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11030
[email protected]f6c63db52013-02-02 00:35:2211031 LoadTimingInfo load_timing_info1;
11032 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11033 TestLoadTimingNotReusedWithPac(load_timing_info1,
11034 CONNECT_TIMING_HAS_SSL_TIMES);
11035
[email protected]8450d722012-07-02 19:14:0411036 // Now, start the HTTP request
11037 HttpRequestInfo request2;
11038 request2.method = "GET";
11039 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411040 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011041 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411042 TestCompletionCallback callback2;
11043 EXPECT_EQ(ERR_IO_PENDING,
11044 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411045 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711046 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411047
11048 EXPECT_EQ(OK, callback2.WaitForResult());
11049 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211050
11051 LoadTimingInfo load_timing_info2;
11052 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11053 // The established SPDY sessions is considered reused by the HTTP request.
11054 TestLoadTimingReusedWithPac(load_timing_info2);
11055 // HTTP requests over a SPDY session should have a different connection
11056 // socket_log_id than requests over a tunnel.
11057 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411058}
11059
[email protected]23e482282013-06-14 16:08:0211060TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411061 HttpStreamFactory::set_force_spdy_always(true);
11062 const std::string https_url = "https://www.google.com/";
11063 const std::string http_url = "http://www.google.com:443/";
11064
11065 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611066 scoped_ptr<SpdyFrame> req1(
11067 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411068 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611069 scoped_ptr<SpdyFrame> req2(
11070 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411071
11072 MockWrite writes[] = {
11073 CreateMockWrite(*req1, 1),
11074 CreateMockWrite(*req2, 4),
11075 };
11076
[email protected]23e482282013-06-14 16:08:0211077 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11078 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11079 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11080 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411081 MockRead reads[] = {
11082 CreateMockRead(*resp1, 2),
11083 CreateMockRead(*body1, 3),
11084 CreateMockRead(*resp2, 5),
11085 CreateMockRead(*body2, 6),
11086 MockRead(ASYNC, ERR_IO_PENDING, 7)
11087 };
11088
[email protected]dd54bd82012-07-19 23:44:5711089 OrderedSocketData data(reads, arraysize(reads),
11090 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411091
[email protected]8450d722012-07-02 19:14:0411092 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211093 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11095 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411096
[email protected]bb88e1d32013-05-03 23:11:0711097 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411098
11099 // Start the first transaction to set up the SpdySession
11100 HttpRequestInfo request1;
11101 request1.method = "GET";
11102 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411103 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011104 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411105 TestCompletionCallback callback1;
11106 EXPECT_EQ(ERR_IO_PENDING,
11107 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411108 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411109
11110 EXPECT_EQ(OK, callback1.WaitForResult());
11111 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11112
11113 // Now, start the HTTP request
11114 HttpRequestInfo request2;
11115 request2.method = "GET";
11116 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411117 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011118 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411119 TestCompletionCallback callback2;
11120 EXPECT_EQ(ERR_IO_PENDING,
11121 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411122 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411123
11124 EXPECT_EQ(OK, callback2.WaitForResult());
11125 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11126}
11127
[email protected]2d88e7d2012-07-19 17:55:1711128// Test that in the case where we have a SPDY session to a SPDY proxy
11129// that we do not pool other origins that resolve to the same IP when
11130// the certificate does not match the new origin.
11131// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211132TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711133 const std::string url1 = "http://www.google.com/";
11134 const std::string url2 = "https://mail.google.com/";
11135 const std::string ip_addr = "1.2.3.4";
11136
11137 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211138 scoped_ptr<SpdyHeaderBlock> headers(
11139 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311140 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211141 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711142
11143 MockWrite writes1[] = {
11144 CreateMockWrite(*req1, 0),
11145 };
11146
[email protected]23e482282013-06-14 16:08:0211147 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11148 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711149 MockRead reads1[] = {
11150 CreateMockRead(*resp1, 1),
11151 CreateMockRead(*body1, 2),
11152 MockRead(ASYNC, OK, 3) // EOF
11153 };
11154
11155 scoped_ptr<DeterministicSocketData> data1(
11156 new DeterministicSocketData(reads1, arraysize(reads1),
11157 writes1, arraysize(writes1)));
11158 IPAddressNumber ip;
11159 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11160 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11161 MockConnect connect_data1(ASYNC, OK, peer_addr);
11162 data1->set_connect_data(connect_data1);
11163
11164 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611165 scoped_ptr<SpdyFrame> req2(
11166 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711167
11168 MockWrite writes2[] = {
11169 CreateMockWrite(*req2, 0),
11170 };
11171
[email protected]23e482282013-06-14 16:08:0211172 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11173 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711174 MockRead reads2[] = {
11175 CreateMockRead(*resp2, 1),
11176 CreateMockRead(*body2, 2),
11177 MockRead(ASYNC, OK, 3) // EOF
11178 };
11179
11180 scoped_ptr<DeterministicSocketData> data2(
11181 new DeterministicSocketData(reads2, arraysize(reads2),
11182 writes2, arraysize(writes2)));
11183 MockConnect connect_data2(ASYNC, OK);
11184 data2->set_connect_data(connect_data2);
11185
11186 // Set up a proxy config that sends HTTP requests to a proxy, and
11187 // all others direct.
11188 ProxyConfig proxy_config;
11189 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11190 CapturingProxyResolver* capturing_proxy_resolver =
11191 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711192 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711193 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11194 NULL));
11195
11196 // Load a valid cert. Note, that this does not need to
11197 // be valid for proxy because the MockSSLClientSocket does
11198 // not actually verify it. But SpdySession will use this
11199 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511200 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711201 scoped_refptr<X509Certificate> server_cert(
11202 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11203 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11204
11205 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211206 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711207 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711208 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11209 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11210 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711211
11212 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211213 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711214 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11215 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11216 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711217
[email protected]bb88e1d32013-05-03 23:11:0711218 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11219 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11220 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711221
11222 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711223 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711224
11225 // Start the first transaction to set up the SpdySession
11226 HttpRequestInfo request1;
11227 request1.method = "GET";
11228 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711229 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011230 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711231 TestCompletionCallback callback1;
11232 ASSERT_EQ(ERR_IO_PENDING,
11233 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11234 data1->RunFor(3);
11235
11236 ASSERT_TRUE(callback1.have_result());
11237 EXPECT_EQ(OK, callback1.WaitForResult());
11238 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11239
11240 // Now, start the HTTP request
11241 HttpRequestInfo request2;
11242 request2.method = "GET";
11243 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711244 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011245 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711246 TestCompletionCallback callback2;
11247 EXPECT_EQ(ERR_IO_PENDING,
11248 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411249 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711250 data2->RunFor(3);
11251
11252 ASSERT_TRUE(callback2.have_result());
11253 EXPECT_EQ(OK, callback2.WaitForResult());
11254 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11255}
11256
[email protected]85f97342013-04-17 06:12:2411257// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11258// error) in SPDY session, removes the socket from pool and closes the SPDY
11259// session. Verify that new url's from the same HttpNetworkSession (and a new
11260// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211261TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411262 const std::string https_url = "https://www.google.com/";
11263
11264 MockRead reads1[] = {
11265 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11266 };
11267
11268 scoped_ptr<DeterministicSocketData> data1(
11269 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11270 data1->SetStop(1);
11271
[email protected]cdf8f7e72013-05-23 10:56:4611272 scoped_ptr<SpdyFrame> req2(
11273 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411274 MockWrite writes2[] = {
11275 CreateMockWrite(*req2, 0),
11276 };
11277
[email protected]23e482282013-06-14 16:08:0211278 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11279 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411280 MockRead reads2[] = {
11281 CreateMockRead(*resp2, 1),
11282 CreateMockRead(*body2, 2),
11283 MockRead(ASYNC, OK, 3) // EOF
11284 };
11285
11286 scoped_ptr<DeterministicSocketData> data2(
11287 new DeterministicSocketData(reads2, arraysize(reads2),
11288 writes2, arraysize(writes2)));
11289
[email protected]85f97342013-04-17 06:12:2411290 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211291 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711292 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11293 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11294 data1.get());
[email protected]85f97342013-04-17 06:12:2411295
11296 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211297 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711298 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11299 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11300 data2.get());
[email protected]85f97342013-04-17 06:12:2411301
11302 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711303 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411304
11305 // Start the first transaction to set up the SpdySession and verify that
11306 // connection was closed.
11307 HttpRequestInfo request1;
11308 request1.method = "GET";
11309 request1.url = GURL(https_url);
11310 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011311 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411312 TestCompletionCallback callback1;
11313 EXPECT_EQ(ERR_IO_PENDING,
11314 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411315 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411316 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11317
11318 // Now, start the second request and make sure it succeeds.
11319 HttpRequestInfo request2;
11320 request2.method = "GET";
11321 request2.url = GURL(https_url);
11322 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011323 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411324 TestCompletionCallback callback2;
11325 EXPECT_EQ(ERR_IO_PENDING,
11326 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411327 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411328 data2->RunFor(3);
11329
11330 ASSERT_TRUE(callback2.have_result());
11331 EXPECT_EQ(OK, callback2.WaitForResult());
11332 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11333}
11334
[email protected]23e482282013-06-14 16:08:0211335TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311336 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11337 ClientSocketPoolManager::set_max_sockets_per_group(
11338 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11339 ClientSocketPoolManager::set_max_sockets_per_pool(
11340 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11341
11342 // Use two different hosts with different IPs so they don't get pooled.
11343 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11344 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11345 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11346
11347 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211348 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311349 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211350 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11353
[email protected]cdf8f7e72013-05-23 10:56:4611354 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311355 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11356 MockWrite spdy1_writes[] = {
11357 CreateMockWrite(*host1_req, 1),
11358 };
[email protected]23e482282013-06-14 16:08:0211359 scoped_ptr<SpdyFrame> host1_resp(
11360 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11361 scoped_ptr<SpdyFrame> host1_resp_body(
11362 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311363 MockRead spdy1_reads[] = {
11364 CreateMockRead(*host1_resp, 2),
11365 CreateMockRead(*host1_resp_body, 3),
11366 MockRead(ASYNC, ERR_IO_PENDING, 4),
11367 };
11368
11369 scoped_ptr<OrderedSocketData> spdy1_data(
11370 new OrderedSocketData(
11371 spdy1_reads, arraysize(spdy1_reads),
11372 spdy1_writes, arraysize(spdy1_writes)));
11373 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11374
[email protected]cdf8f7e72013-05-23 10:56:4611375 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311376 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11377 MockWrite spdy2_writes[] = {
11378 CreateMockWrite(*host2_req, 1),
11379 };
[email protected]23e482282013-06-14 16:08:0211380 scoped_ptr<SpdyFrame> host2_resp(
11381 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11382 scoped_ptr<SpdyFrame> host2_resp_body(
11383 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311384 MockRead spdy2_reads[] = {
11385 CreateMockRead(*host2_resp, 2),
11386 CreateMockRead(*host2_resp_body, 3),
11387 MockRead(ASYNC, ERR_IO_PENDING, 4),
11388 };
11389
11390 scoped_ptr<OrderedSocketData> spdy2_data(
11391 new OrderedSocketData(
11392 spdy2_reads, arraysize(spdy2_reads),
11393 spdy2_writes, arraysize(spdy2_writes)));
11394 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11395
11396 MockWrite http_write[] = {
11397 MockWrite("GET / HTTP/1.1\r\n"
11398 "Host: www.a.com\r\n"
11399 "Connection: keep-alive\r\n\r\n"),
11400 };
11401
11402 MockRead http_read[] = {
11403 MockRead("HTTP/1.1 200 OK\r\n"),
11404 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11405 MockRead("Content-Length: 6\r\n\r\n"),
11406 MockRead("hello!"),
11407 };
11408 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11409 http_write, arraysize(http_write));
11410 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11411
11412 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011413 SpdySessionKey spdy_session_key_a(
11414 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311415 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611416 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311417
11418 TestCompletionCallback callback;
11419 HttpRequestInfo request1;
11420 request1.method = "GET";
11421 request1.url = GURL("https://www.a.com/");
11422 request1.load_flags = 0;
11423 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011424 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311425
11426 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11427 EXPECT_EQ(ERR_IO_PENDING, rv);
11428 EXPECT_EQ(OK, callback.WaitForResult());
11429
11430 const HttpResponseInfo* response = trans->GetResponseInfo();
11431 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011432 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311433 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11434 EXPECT_TRUE(response->was_fetched_via_spdy);
11435 EXPECT_TRUE(response->was_npn_negotiated);
11436
11437 std::string response_data;
11438 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11439 EXPECT_EQ("hello!", response_data);
11440 trans.reset();
11441 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611442 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311443
11444 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011445 SpdySessionKey spdy_session_key_b(
11446 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311447 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611448 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311449 HttpRequestInfo request2;
11450 request2.method = "GET";
11451 request2.url = GURL("https://www.b.com/");
11452 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011453 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311454
11455 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11456 EXPECT_EQ(ERR_IO_PENDING, rv);
11457 EXPECT_EQ(OK, callback.WaitForResult());
11458
11459 response = trans->GetResponseInfo();
11460 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011461 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311462 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11463 EXPECT_TRUE(response->was_fetched_via_spdy);
11464 EXPECT_TRUE(response->was_npn_negotiated);
11465 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11466 EXPECT_EQ("hello!", response_data);
11467 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611468 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311469 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611470 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311471
11472 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011473 SpdySessionKey spdy_session_key_a1(
11474 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311475 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611476 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311477 HttpRequestInfo request3;
11478 request3.method = "GET";
11479 request3.url = GURL("http://www.a.com/");
11480 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011481 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311482
11483 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11484 EXPECT_EQ(ERR_IO_PENDING, rv);
11485 EXPECT_EQ(OK, callback.WaitForResult());
11486
11487 response = trans->GetResponseInfo();
11488 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011489 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311490 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11491 EXPECT_FALSE(response->was_fetched_via_spdy);
11492 EXPECT_FALSE(response->was_npn_negotiated);
11493 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11494 EXPECT_EQ("hello!", response_data);
11495 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611496 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311497 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611498 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311499}
11500
[email protected]79e1fd62013-06-20 06:50:0411501TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11502 HttpRequestInfo request;
11503 request.method = "GET";
11504 request.url = GURL("http://www.google.com/");
11505 request.load_flags = 0;
11506
[email protected]3fe8d2f82013-10-17 08:56:0711507 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411508 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711509 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411510
11511 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11512 StaticSocketDataProvider data;
11513 data.set_connect_data(mock_connect);
11514 session_deps_.socket_factory->AddSocketDataProvider(&data);
11515
11516 TestCompletionCallback callback;
11517
11518 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11519 EXPECT_EQ(ERR_IO_PENDING, rv);
11520
11521 rv = callback.WaitForResult();
11522 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11523
11524 EXPECT_EQ(NULL, trans->GetResponseInfo());
11525
11526 // We don't care whether this succeeds or fails, but it shouldn't crash.
11527 HttpRequestHeaders request_headers;
11528 trans->GetFullRequestHeaders(&request_headers);
11529}
11530
11531TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11532 HttpRequestInfo request;
11533 request.method = "GET";
11534 request.url = GURL("http://www.google.com/");
11535 request.load_flags = 0;
11536
[email protected]3fe8d2f82013-10-17 08:56:0711537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411538 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411540
11541 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11542 StaticSocketDataProvider data;
11543 data.set_connect_data(mock_connect);
11544 session_deps_.socket_factory->AddSocketDataProvider(&data);
11545
11546 TestCompletionCallback callback;
11547
11548 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11549 EXPECT_EQ(ERR_IO_PENDING, rv);
11550
11551 rv = callback.WaitForResult();
11552 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11553
11554 EXPECT_EQ(NULL, trans->GetResponseInfo());
11555
11556 // We don't care whether this succeeds or fails, but it shouldn't crash.
11557 HttpRequestHeaders request_headers;
11558 trans->GetFullRequestHeaders(&request_headers);
11559}
11560
11561TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11562 HttpRequestInfo request;
11563 request.method = "GET";
11564 request.url = GURL("http://www.google.com/");
11565 request.load_flags = 0;
11566
[email protected]3fe8d2f82013-10-17 08:56:0711567 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411568 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411570
11571 MockWrite data_writes[] = {
11572 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11573 };
11574 MockRead data_reads[] = {
11575 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11576 };
11577
11578 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11579 data_writes, arraysize(data_writes));
11580 session_deps_.socket_factory->AddSocketDataProvider(&data);
11581
11582 TestCompletionCallback callback;
11583
11584 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11585 EXPECT_EQ(ERR_IO_PENDING, rv);
11586
11587 rv = callback.WaitForResult();
11588 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11589
11590 EXPECT_EQ(NULL, trans->GetResponseInfo());
11591
11592 HttpRequestHeaders request_headers;
11593 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11594 EXPECT_TRUE(request_headers.HasHeader("Host"));
11595}
11596
11597TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11598 HttpRequestInfo request;
11599 request.method = "GET";
11600 request.url = GURL("http://www.google.com/");
11601 request.load_flags = 0;
11602
[email protected]3fe8d2f82013-10-17 08:56:0711603 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411604 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411606
11607 MockWrite data_writes[] = {
11608 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11609 };
11610 MockRead data_reads[] = {
11611 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11612 };
11613
11614 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11615 data_writes, arraysize(data_writes));
11616 session_deps_.socket_factory->AddSocketDataProvider(&data);
11617
11618 TestCompletionCallback callback;
11619
11620 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11621 EXPECT_EQ(ERR_IO_PENDING, rv);
11622
11623 rv = callback.WaitForResult();
11624 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11625
11626 EXPECT_EQ(NULL, trans->GetResponseInfo());
11627
11628 HttpRequestHeaders request_headers;
11629 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11630 EXPECT_TRUE(request_headers.HasHeader("Host"));
11631}
11632
11633TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11634 HttpRequestInfo request;
11635 request.method = "GET";
11636 request.url = GURL("http://www.google.com/");
11637 request.load_flags = 0;
11638
[email protected]3fe8d2f82013-10-17 08:56:0711639 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411640 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711641 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411642
11643 MockWrite data_writes[] = {
11644 MockWrite("GET / HTTP/1.1\r\n"
11645 "Host: www.google.com\r\n"
11646 "Connection: keep-alive\r\n\r\n"),
11647 };
11648 MockRead data_reads[] = {
11649 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11650 };
11651
11652 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11653 data_writes, arraysize(data_writes));
11654 session_deps_.socket_factory->AddSocketDataProvider(&data);
11655
11656 TestCompletionCallback callback;
11657
11658 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11659 EXPECT_EQ(ERR_IO_PENDING, rv);
11660
11661 rv = callback.WaitForResult();
11662 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11663
11664 EXPECT_EQ(NULL, trans->GetResponseInfo());
11665
11666 HttpRequestHeaders request_headers;
11667 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11668 EXPECT_TRUE(request_headers.HasHeader("Host"));
11669}
11670
11671TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11672 HttpRequestInfo request;
11673 request.method = "GET";
11674 request.url = GURL("http://www.google.com/");
11675 request.load_flags = 0;
11676
[email protected]3fe8d2f82013-10-17 08:56:0711677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411678 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411680
11681 MockWrite data_writes[] = {
11682 MockWrite("GET / HTTP/1.1\r\n"
11683 "Host: www.google.com\r\n"
11684 "Connection: keep-alive\r\n\r\n"),
11685 };
11686 MockRead data_reads[] = {
11687 MockRead(ASYNC, ERR_CONNECTION_RESET),
11688 };
11689
11690 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11691 data_writes, arraysize(data_writes));
11692 session_deps_.socket_factory->AddSocketDataProvider(&data);
11693
11694 TestCompletionCallback callback;
11695
11696 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11697 EXPECT_EQ(ERR_IO_PENDING, rv);
11698
11699 rv = callback.WaitForResult();
11700 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11701
11702 EXPECT_EQ(NULL, trans->GetResponseInfo());
11703
11704 HttpRequestHeaders request_headers;
11705 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11706 EXPECT_TRUE(request_headers.HasHeader("Host"));
11707}
11708
11709TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11710 HttpRequestInfo request;
11711 request.method = "GET";
11712 request.url = GURL("http://www.google.com/");
11713 request.load_flags = 0;
11714 request.extra_headers.SetHeader("X-Foo", "bar");
11715
[email protected]3fe8d2f82013-10-17 08:56:0711716 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411717 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711718 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411719
11720 MockWrite data_writes[] = {
11721 MockWrite("GET / HTTP/1.1\r\n"
11722 "Host: www.google.com\r\n"
11723 "Connection: keep-alive\r\n"
11724 "X-Foo: bar\r\n\r\n"),
11725 };
11726 MockRead data_reads[] = {
11727 MockRead("HTTP/1.1 200 OK\r\n"
11728 "Content-Length: 5\r\n\r\n"
11729 "hello"),
11730 MockRead(ASYNC, ERR_UNEXPECTED),
11731 };
11732
11733 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11734 data_writes, arraysize(data_writes));
11735 session_deps_.socket_factory->AddSocketDataProvider(&data);
11736
11737 TestCompletionCallback callback;
11738
11739 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11740 EXPECT_EQ(ERR_IO_PENDING, rv);
11741
11742 rv = callback.WaitForResult();
11743 EXPECT_EQ(OK, rv);
11744
11745 HttpRequestHeaders request_headers;
11746 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11747 std::string foo;
11748 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11749 EXPECT_EQ("bar", foo);
11750}
11751
[email protected]bf828982013-08-14 18:01:4711752namespace {
11753
[email protected]e86839fd2013-08-14 18:29:0311754// Fake HttpStreamBase that simply records calls to SetPriority().
11755class FakeStream : public HttpStreamBase,
11756 public base::SupportsWeakPtr<FakeStream> {
11757 public:
11758 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
11759 virtual ~FakeStream() {}
11760
11761 RequestPriority priority() const { return priority_; }
11762
11763 virtual int InitializeStream(const HttpRequestInfo* request_info,
11764 RequestPriority priority,
11765 const BoundNetLog& net_log,
11766 const CompletionCallback& callback) OVERRIDE {
11767 return ERR_IO_PENDING;
11768 }
11769
11770 virtual int SendRequest(const HttpRequestHeaders& request_headers,
11771 HttpResponseInfo* response,
11772 const CompletionCallback& callback) OVERRIDE {
11773 ADD_FAILURE();
11774 return ERR_UNEXPECTED;
11775 }
11776
11777 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
11778 ADD_FAILURE();
11779 return ERR_UNEXPECTED;
11780 }
11781
11782 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
11783 ADD_FAILURE();
11784 return NULL;
11785 }
11786
11787 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
11788 const CompletionCallback& callback) OVERRIDE {
11789 ADD_FAILURE();
11790 return ERR_UNEXPECTED;
11791 }
11792
11793 virtual void Close(bool not_reusable) OVERRIDE {}
11794
11795 virtual bool IsResponseBodyComplete() const OVERRIDE {
11796 ADD_FAILURE();
11797 return false;
11798 }
11799
11800 virtual bool CanFindEndOfResponse() const OVERRIDE {
11801 return false;
11802 }
11803
11804 virtual bool IsConnectionReused() const OVERRIDE {
11805 ADD_FAILURE();
11806 return false;
11807 }
11808
11809 virtual void SetConnectionReused() OVERRIDE {
11810 ADD_FAILURE();
11811 }
11812
11813 virtual bool IsConnectionReusable() const OVERRIDE {
11814 ADD_FAILURE();
11815 return false;
11816 }
11817
11818 virtual bool GetLoadTimingInfo(
11819 LoadTimingInfo* load_timing_info) const OVERRIDE {
11820 ADD_FAILURE();
11821 return false;
11822 }
11823
11824 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
11825 ADD_FAILURE();
11826 }
11827
11828 virtual void GetSSLCertRequestInfo(
11829 SSLCertRequestInfo* cert_request_info) OVERRIDE {
11830 ADD_FAILURE();
11831 }
11832
11833 virtual bool IsSpdyHttpStream() const OVERRIDE {
11834 ADD_FAILURE();
11835 return false;
11836 }
11837
11838 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
11839 ADD_FAILURE();
11840 }
11841
11842 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11843 priority_ = priority;
11844 }
11845
11846 private:
11847 RequestPriority priority_;
11848
11849 DISALLOW_COPY_AND_ASSIGN(FakeStream);
11850};
11851
11852// Fake HttpStreamRequest that simply records calls to SetPriority()
11853// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4711854class FakeStreamRequest : public HttpStreamRequest,
11855 public base::SupportsWeakPtr<FakeStreamRequest> {
11856 public:
[email protected]e86839fd2013-08-14 18:29:0311857 FakeStreamRequest(RequestPriority priority,
11858 HttpStreamRequest::Delegate* delegate)
11859 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4411860 delegate_(delegate),
11861 websocket_stream_create_helper_(NULL) {}
11862
11863 FakeStreamRequest(RequestPriority priority,
11864 HttpStreamRequest::Delegate* delegate,
11865 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
11866 : priority_(priority),
11867 delegate_(delegate),
11868 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0311869
[email protected]bf828982013-08-14 18:01:4711870 virtual ~FakeStreamRequest() {}
11871
11872 RequestPriority priority() const { return priority_; }
11873
[email protected]831e4a32013-11-14 02:14:4411874 const WebSocketHandshakeStreamBase::CreateHelper*
11875 websocket_stream_create_helper() const {
11876 return websocket_stream_create_helper_;
11877 }
11878
[email protected]e86839fd2013-08-14 18:29:0311879 // Create a new FakeStream and pass it to the request's
11880 // delegate. Returns a weak pointer to the FakeStream.
11881 base::WeakPtr<FakeStream> FinishStreamRequest() {
11882 FakeStream* fake_stream = new FakeStream(priority_);
11883 // Do this before calling OnStreamReady() as OnStreamReady() may
11884 // immediately delete |fake_stream|.
11885 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
11886 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
11887 return weak_stream;
11888 }
11889
[email protected]bf828982013-08-14 18:01:4711890 virtual int RestartTunnelWithProxyAuth(
11891 const AuthCredentials& credentials) OVERRIDE {
11892 ADD_FAILURE();
11893 return ERR_UNEXPECTED;
11894 }
11895
11896 virtual LoadState GetLoadState() const OVERRIDE {
11897 ADD_FAILURE();
11898 return LoadState();
11899 }
11900
11901 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11902 priority_ = priority;
11903 }
11904
11905 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711906 return false;
11907 }
11908
11909 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711910 return kProtoUnknown;
11911 }
11912
11913 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711914 return false;
11915 }
11916
11917 private:
11918 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0311919 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4411920 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4711921
11922 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
11923};
11924
11925// Fake HttpStreamFactory that vends FakeStreamRequests.
11926class FakeStreamFactory : public HttpStreamFactory {
11927 public:
11928 FakeStreamFactory() {}
11929 virtual ~FakeStreamFactory() {}
11930
11931 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
11932 // RequestStream() (which may be NULL if it was destroyed already).
11933 base::WeakPtr<FakeStreamRequest> last_stream_request() {
11934 return last_stream_request_;
11935 }
11936
11937 virtual HttpStreamRequest* RequestStream(
11938 const HttpRequestInfo& info,
11939 RequestPriority priority,
11940 const SSLConfig& server_ssl_config,
11941 const SSLConfig& proxy_ssl_config,
11942 HttpStreamRequest::Delegate* delegate,
11943 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0311944 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4711945 last_stream_request_ = fake_request->AsWeakPtr();
11946 return fake_request;
11947 }
11948
[email protected]a9cf2b92013-10-30 12:08:4911949 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4711950 const HttpRequestInfo& info,
11951 RequestPriority priority,
11952 const SSLConfig& server_ssl_config,
11953 const SSLConfig& proxy_ssl_config,
11954 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4611955 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4711956 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4411957 FakeStreamRequest* fake_request =
11958 new FakeStreamRequest(priority, delegate, create_helper);
11959 last_stream_request_ = fake_request->AsWeakPtr();
11960 return fake_request;
[email protected]bf828982013-08-14 18:01:4711961 }
11962
11963 virtual void PreconnectStreams(int num_streams,
11964 const HttpRequestInfo& info,
11965 RequestPriority priority,
11966 const SSLConfig& server_ssl_config,
11967 const SSLConfig& proxy_ssl_config) OVERRIDE {
11968 ADD_FAILURE();
11969 }
11970
11971 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
11972 ADD_FAILURE();
11973 return NULL;
11974 }
11975
11976 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
11977 ADD_FAILURE();
11978 return NULL;
11979 }
11980
11981 private:
11982 base::WeakPtr<FakeStreamRequest> last_stream_request_;
11983
11984 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
11985};
11986
[email protected]831e4a32013-11-14 02:14:4411987// TODO(yhirano): Split this class out into a net/websockets file, if it is
11988// worth doing.
11989class FakeWebSocketStreamCreateHelper :
11990 public WebSocketHandshakeStreamBase::CreateHelper {
11991 public:
11992 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2111993 scoped_ptr<ClientSocketHandle> connection,
[email protected]831e4a32013-11-14 02:14:4411994 bool using_proxy) OVERRIDE {
11995 NOTREACHED();
11996 return NULL;
11997 }
11998
11999 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12000 const base::WeakPtr<SpdySession>& session,
12001 bool use_relative_url) OVERRIDE {
12002 NOTREACHED();
12003 return NULL;
12004 };
12005
12006 virtual ~FakeWebSocketStreamCreateHelper() {}
12007
12008 virtual scoped_ptr<WebSocketStream> Upgrade() {
12009 NOTREACHED();
12010 return scoped_ptr<WebSocketStream>();
12011 }
12012};
12013
[email protected]bf828982013-08-14 18:01:4712014} // namespace
12015
12016// Make sure that HttpNetworkTransaction passes on its priority to its
12017// stream request on start.
12018TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12019 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12020 HttpNetworkSessionPeer peer(session);
12021 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412022 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712023
12024 HttpNetworkTransaction trans(LOW, session);
12025
12026 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12027
12028 HttpRequestInfo request;
12029 TestCompletionCallback callback;
12030 EXPECT_EQ(ERR_IO_PENDING,
12031 trans.Start(&request, callback.callback(), BoundNetLog()));
12032
12033 base::WeakPtr<FakeStreamRequest> fake_request =
12034 fake_factory->last_stream_request();
12035 ASSERT_TRUE(fake_request != NULL);
12036 EXPECT_EQ(LOW, fake_request->priority());
12037}
12038
12039// Make sure that HttpNetworkTransaction passes on its priority
12040// updates to its stream request.
12041TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12042 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12043 HttpNetworkSessionPeer peer(session);
12044 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412045 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712046
12047 HttpNetworkTransaction trans(LOW, session);
12048
12049 HttpRequestInfo request;
12050 TestCompletionCallback callback;
12051 EXPECT_EQ(ERR_IO_PENDING,
12052 trans.Start(&request, callback.callback(), BoundNetLog()));
12053
12054 base::WeakPtr<FakeStreamRequest> fake_request =
12055 fake_factory->last_stream_request();
12056 ASSERT_TRUE(fake_request != NULL);
12057 EXPECT_EQ(LOW, fake_request->priority());
12058
12059 trans.SetPriority(LOWEST);
12060 ASSERT_TRUE(fake_request != NULL);
12061 EXPECT_EQ(LOWEST, fake_request->priority());
12062}
12063
[email protected]e86839fd2013-08-14 18:29:0312064// Make sure that HttpNetworkTransaction passes on its priority
12065// updates to its stream.
12066TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12067 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12068 HttpNetworkSessionPeer peer(session);
12069 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412070 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312071
12072 HttpNetworkTransaction trans(LOW, session);
12073
12074 HttpRequestInfo request;
12075 TestCompletionCallback callback;
12076 EXPECT_EQ(ERR_IO_PENDING,
12077 trans.Start(&request, callback.callback(), BoundNetLog()));
12078
12079 base::WeakPtr<FakeStreamRequest> fake_request =
12080 fake_factory->last_stream_request();
12081 ASSERT_TRUE(fake_request != NULL);
12082 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12083 ASSERT_TRUE(fake_stream != NULL);
12084 EXPECT_EQ(LOW, fake_stream->priority());
12085
12086 trans.SetPriority(LOWEST);
12087 EXPECT_EQ(LOWEST, fake_stream->priority());
12088}
12089
[email protected]831e4a32013-11-14 02:14:4412090TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12091 // The same logic needs to be tested for both ws: and wss: schemes, but this
12092 // test is already parameterised on NextProto, so it uses a loop to verify
12093 // that the different schemes work.
12094 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12095 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12096 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12097 HttpNetworkSessionPeer peer(session);
12098 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12099 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312100 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412101 scoped_ptr<HttpStreamFactory>(fake_factory));
12102
12103 HttpNetworkTransaction trans(LOW, session);
12104 trans.SetWebSocketHandshakeStreamCreateHelper(
12105 &websocket_stream_create_helper);
12106
12107 HttpRequestInfo request;
12108 TestCompletionCallback callback;
12109 request.method = "GET";
12110 request.url = GURL(test_cases[i]);
12111
12112 EXPECT_EQ(ERR_IO_PENDING,
12113 trans.Start(&request, callback.callback(), BoundNetLog()));
12114
12115 base::WeakPtr<FakeStreamRequest> fake_request =
12116 fake_factory->last_stream_request();
12117 ASSERT_TRUE(fake_request != NULL);
12118 EXPECT_EQ(&websocket_stream_create_helper,
12119 fake_request->websocket_stream_create_helper());
12120 }
12121}
12122
[email protected]043b68c82013-08-22 23:41:5212123// Tests that when a used socket is returned to the SSL socket pool, it's closed
12124// if the transport socket pool is stalled on the global socket limit.
12125TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12126 ClientSocketPoolManager::set_max_sockets_per_group(
12127 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12128 ClientSocketPoolManager::set_max_sockets_per_pool(
12129 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12130
12131 // Set up SSL request.
12132
12133 HttpRequestInfo ssl_request;
12134 ssl_request.method = "GET";
12135 ssl_request.url = GURL("https://www.google.com/");
12136
12137 MockWrite ssl_writes[] = {
12138 MockWrite("GET / HTTP/1.1\r\n"
12139 "Host: www.google.com\r\n"
12140 "Connection: keep-alive\r\n\r\n"),
12141 };
12142 MockRead ssl_reads[] = {
12143 MockRead("HTTP/1.1 200 OK\r\n"),
12144 MockRead("Content-Length: 11\r\n\r\n"),
12145 MockRead("hello world"),
12146 MockRead(SYNCHRONOUS, OK),
12147 };
12148 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12149 ssl_writes, arraysize(ssl_writes));
12150 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12151
12152 SSLSocketDataProvider ssl(ASYNC, OK);
12153 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12154
12155 // Set up HTTP request.
12156
12157 HttpRequestInfo http_request;
12158 http_request.method = "GET";
12159 http_request.url = GURL("http://www.google.com/");
12160
12161 MockWrite http_writes[] = {
12162 MockWrite("GET / HTTP/1.1\r\n"
12163 "Host: www.google.com\r\n"
12164 "Connection: keep-alive\r\n\r\n"),
12165 };
12166 MockRead http_reads[] = {
12167 MockRead("HTTP/1.1 200 OK\r\n"),
12168 MockRead("Content-Length: 7\r\n\r\n"),
12169 MockRead("falafel"),
12170 MockRead(SYNCHRONOUS, OK),
12171 };
12172 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12173 http_writes, arraysize(http_writes));
12174 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12175
12176 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12177
12178 // Start the SSL request.
12179 TestCompletionCallback ssl_callback;
12180 scoped_ptr<HttpTransaction> ssl_trans(
12181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12182 ASSERT_EQ(ERR_IO_PENDING,
12183 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12184 BoundNetLog()));
12185
12186 // Start the HTTP request. Pool should stall.
12187 TestCompletionCallback http_callback;
12188 scoped_ptr<HttpTransaction> http_trans(
12189 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12190 ASSERT_EQ(ERR_IO_PENDING,
12191 http_trans->Start(&http_request, http_callback.callback(),
12192 BoundNetLog()));
12193 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12194
12195 // Wait for response from SSL request.
12196 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12197 std::string response_data;
12198 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12199 EXPECT_EQ("hello world", response_data);
12200
12201 // The SSL socket should automatically be closed, so the HTTP request can
12202 // start.
12203 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12204 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12205
12206 // The HTTP request can now complete.
12207 ASSERT_EQ(OK, http_callback.WaitForResult());
12208 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12209 EXPECT_EQ("falafel", response_data);
12210
12211 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12212}
12213
12214// Tests that when a SSL connection is established but there's no corresponding
12215// request that needs it, the new socket is closed if the transport socket pool
12216// is stalled on the global socket limit.
12217TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12218 ClientSocketPoolManager::set_max_sockets_per_group(
12219 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12220 ClientSocketPoolManager::set_max_sockets_per_pool(
12221 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12222
12223 // Set up an ssl request.
12224
12225 HttpRequestInfo ssl_request;
12226 ssl_request.method = "GET";
12227 ssl_request.url = GURL("https://www.foopy.com/");
12228
12229 // No data will be sent on the SSL socket.
12230 StaticSocketDataProvider ssl_data;
12231 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12232
12233 SSLSocketDataProvider ssl(ASYNC, OK);
12234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12235
12236 // Set up HTTP request.
12237
12238 HttpRequestInfo http_request;
12239 http_request.method = "GET";
12240 http_request.url = GURL("http://www.google.com/");
12241
12242 MockWrite http_writes[] = {
12243 MockWrite("GET / HTTP/1.1\r\n"
12244 "Host: www.google.com\r\n"
12245 "Connection: keep-alive\r\n\r\n"),
12246 };
12247 MockRead http_reads[] = {
12248 MockRead("HTTP/1.1 200 OK\r\n"),
12249 MockRead("Content-Length: 7\r\n\r\n"),
12250 MockRead("falafel"),
12251 MockRead(SYNCHRONOUS, OK),
12252 };
12253 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12254 http_writes, arraysize(http_writes));
12255 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12256
12257 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12258
12259 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12260 // cancelled when a normal transaction is cancelled.
12261 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12262 net::SSLConfig ssl_config;
12263 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12264 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12265 ssl_config, ssl_config);
12266 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12267
12268 // Start the HTTP request. Pool should stall.
12269 TestCompletionCallback http_callback;
12270 scoped_ptr<HttpTransaction> http_trans(
12271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12272 ASSERT_EQ(ERR_IO_PENDING,
12273 http_trans->Start(&http_request, http_callback.callback(),
12274 BoundNetLog()));
12275 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12276
12277 // The SSL connection will automatically be closed once the connection is
12278 // established, to let the HTTP request start.
12279 ASSERT_EQ(OK, http_callback.WaitForResult());
12280 std::string response_data;
12281 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12282 EXPECT_EQ("falafel", response_data);
12283
12284 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12285}
12286
[email protected]89ceba9a2009-03-21 03:46:0612287} // namespace net