blob: f23d0fb331e1e2e368f5757628b60a935c5df0b4 [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,
515 std::string(),
516 NULL,
517 NULL,
518 NULL,
519 NULL,
520 NULL,
521 NULL) {}
[email protected]2227c692010-05-04 15:36:11522
[email protected]231d5a32008-09-13 00:45:27523//-----------------------------------------------------------------------------
524
[email protected]79cb5c12011-09-12 13:12:04525// Helper functions for validating that AuthChallengeInfo's are correctly
526// configured for common cases.
527bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
528 if (!auth_challenge)
529 return false;
530 EXPECT_FALSE(auth_challenge->is_proxy);
531 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
532 EXPECT_EQ("MyRealm1", auth_challenge->realm);
533 EXPECT_EQ("basic", auth_challenge->scheme);
534 return true;
535}
536
537bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
538 if (!auth_challenge)
539 return false;
540 EXPECT_TRUE(auth_challenge->is_proxy);
541 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
542 EXPECT_EQ("MyRealm1", auth_challenge->realm);
543 EXPECT_EQ("basic", auth_challenge->scheme);
544 return true;
545}
546
547bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
548 if (!auth_challenge)
549 return false;
550 EXPECT_FALSE(auth_challenge->is_proxy);
551 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
552 EXPECT_EQ("digestive", auth_challenge->realm);
553 EXPECT_EQ("digest", auth_challenge->scheme);
554 return true;
555}
556
557bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
558 if (!auth_challenge)
559 return false;
560 EXPECT_FALSE(auth_challenge->is_proxy);
561 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
562 EXPECT_EQ(std::string(), auth_challenge->realm);
563 EXPECT_EQ("ntlm", auth_challenge->scheme);
564 return true;
565}
566
[email protected]448d4ca52012-03-04 04:12:23567} // namespace
568
[email protected]23e482282013-06-14 16:08:02569TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07570 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40571 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07572 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27573}
574
[email protected]23e482282013-06-14 16:08:02575TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27576 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35577 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
578 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06579 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27580 };
[email protected]31a2bfe2010-02-09 08:03:39581 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
582 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42583 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27584 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
585 EXPECT_EQ("hello world", out.response_data);
586}
587
588// Response with no status line.
[email protected]23e482282013-06-14 16:08:02589TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27590 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35591 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06592 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27593 };
[email protected]31a2bfe2010-02-09 08:03:39594 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
595 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42596 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27597 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
598 EXPECT_EQ("hello world", out.response_data);
599}
600
601// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02602TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27603 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35604 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06605 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27606 };
[email protected]31a2bfe2010-02-09 08:03:39607 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
608 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42609 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27610 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
611 EXPECT_EQ("DATA", out.response_data);
612}
613
614// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02615TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27616 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35617 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06618 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27619 };
[email protected]31a2bfe2010-02-09 08:03:39620 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
621 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42622 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27623 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
624 EXPECT_EQ("DATA", out.response_data);
625}
626
627// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02628TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27629 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35630 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06631 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27632 };
[email protected]31a2bfe2010-02-09 08:03:39633 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
634 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42635 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25636 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
637 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27638}
639
640// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02641TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27642 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35643 MockRead("\n"),
644 MockRead("\n"),
645 MockRead("Q"),
646 MockRead("J"),
647 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06648 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27649 };
[email protected]31a2bfe2010-02-09 08:03:39650 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
651 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42652 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27653 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
654 EXPECT_EQ("DATA", out.response_data);
655}
656
657// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02658TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27659 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35660 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06661 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27662 };
[email protected]31a2bfe2010-02-09 08:03:39663 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
664 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42665 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27666 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
667 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52668}
669
[email protected]f9d44aa2008-09-23 23:57:17670// Simulate a 204 response, lacking a Content-Length header, sent over a
671// persistent connection. The response should still terminate since a 204
672// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02673TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]f9d44aa2008-09-23 23:57:17674 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35675 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
676 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06677 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17678 };
[email protected]31a2bfe2010-02-09 08:03:39679 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
680 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42681 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17682 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
683 EXPECT_EQ("", out.response_data);
684}
685
[email protected]0877e3d2009-10-17 22:29:57686// A simple request using chunked encoding with some extra data after.
687// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02688TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]0877e3d2009-10-17 22:29:57689 MockRead data_reads[] = {
690 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
691 MockRead("5\r\nHello\r\n"),
692 MockRead("1\r\n"),
693 MockRead(" \r\n"),
694 MockRead("5\r\nworld\r\n"),
695 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06696 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57697 };
[email protected]31a2bfe2010-02-09 08:03:39698 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
699 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57700 EXPECT_EQ(OK, out.rv);
701 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
702 EXPECT_EQ("Hello world", out.response_data);
703}
704
[email protected]9fe44f52010-09-23 18:36:00705// Next tests deal with http://crbug.com/56344.
706
[email protected]23e482282013-06-14 16:08:02707TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00708 MultipleContentLengthHeadersNoTransferEncoding) {
709 MockRead data_reads[] = {
710 MockRead("HTTP/1.1 200 OK\r\n"),
711 MockRead("Content-Length: 10\r\n"),
712 MockRead("Content-Length: 5\r\n\r\n"),
713 };
714 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
715 arraysize(data_reads));
716 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
717}
718
[email protected]23e482282013-06-14 16:08:02719TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04720 DuplicateContentLengthHeadersNoTransferEncoding) {
721 MockRead data_reads[] = {
722 MockRead("HTTP/1.1 200 OK\r\n"),
723 MockRead("Content-Length: 5\r\n"),
724 MockRead("Content-Length: 5\r\n\r\n"),
725 MockRead("Hello"),
726 };
727 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
728 arraysize(data_reads));
729 EXPECT_EQ(OK, out.rv);
730 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
731 EXPECT_EQ("Hello", out.response_data);
732}
733
[email protected]23e482282013-06-14 16:08:02734TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04735 ComplexContentLengthHeadersNoTransferEncoding) {
736 // More than 2 dupes.
737 {
738 MockRead data_reads[] = {
739 MockRead("HTTP/1.1 200 OK\r\n"),
740 MockRead("Content-Length: 5\r\n"),
741 MockRead("Content-Length: 5\r\n"),
742 MockRead("Content-Length: 5\r\n\r\n"),
743 MockRead("Hello"),
744 };
745 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
746 arraysize(data_reads));
747 EXPECT_EQ(OK, out.rv);
748 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
749 EXPECT_EQ("Hello", out.response_data);
750 }
751 // HTTP/1.0
752 {
753 MockRead data_reads[] = {
754 MockRead("HTTP/1.0 200 OK\r\n"),
755 MockRead("Content-Length: 5\r\n"),
756 MockRead("Content-Length: 5\r\n"),
757 MockRead("Content-Length: 5\r\n\r\n"),
758 MockRead("Hello"),
759 };
760 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
761 arraysize(data_reads));
762 EXPECT_EQ(OK, out.rv);
763 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
764 EXPECT_EQ("Hello", out.response_data);
765 }
766 // 2 dupes and one mismatched.
767 {
768 MockRead data_reads[] = {
769 MockRead("HTTP/1.1 200 OK\r\n"),
770 MockRead("Content-Length: 10\r\n"),
771 MockRead("Content-Length: 10\r\n"),
772 MockRead("Content-Length: 5\r\n\r\n"),
773 };
774 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
775 arraysize(data_reads));
776 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
777 }
778}
779
[email protected]23e482282013-06-14 16:08:02780TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00781 MultipleContentLengthHeadersTransferEncoding) {
782 MockRead data_reads[] = {
783 MockRead("HTTP/1.1 200 OK\r\n"),
784 MockRead("Content-Length: 666\r\n"),
785 MockRead("Content-Length: 1337\r\n"),
786 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
787 MockRead("5\r\nHello\r\n"),
788 MockRead("1\r\n"),
789 MockRead(" \r\n"),
790 MockRead("5\r\nworld\r\n"),
791 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06792 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00793 };
794 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
795 arraysize(data_reads));
796 EXPECT_EQ(OK, out.rv);
797 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
798 EXPECT_EQ("Hello world", out.response_data);
799}
800
[email protected]1628fe92011-10-04 23:04:55801// Next tests deal with http://crbug.com/98895.
802
803// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02804TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55805 MockRead data_reads[] = {
806 MockRead("HTTP/1.1 200 OK\r\n"),
807 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
808 MockRead("Content-Length: 5\r\n\r\n"),
809 MockRead("Hello"),
810 };
811 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
812 arraysize(data_reads));
813 EXPECT_EQ(OK, out.rv);
814 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
815 EXPECT_EQ("Hello", out.response_data);
816}
817
[email protected]54a9c6e52012-03-21 20:10:59818// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02819TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59820 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55821 MockRead data_reads[] = {
822 MockRead("HTTP/1.1 200 OK\r\n"),
823 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
824 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
825 MockRead("Content-Length: 5\r\n\r\n"),
826 MockRead("Hello"),
827 };
828 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
829 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59830 EXPECT_EQ(OK, out.rv);
831 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
832 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55833}
834
835// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02836TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55837 MockRead data_reads[] = {
838 MockRead("HTTP/1.1 200 OK\r\n"),
839 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
840 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
841 MockRead("Content-Length: 5\r\n\r\n"),
842 MockRead("Hello"),
843 };
844 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
845 arraysize(data_reads));
846 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
847}
848
[email protected]54a9c6e52012-03-21 20:10:59849// Checks that two identical Location headers result in no error.
850// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02851TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55852 MockRead data_reads[] = {
853 MockRead("HTTP/1.1 302 Redirect\r\n"),
854 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59855 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55856 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06857 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55858 };
859
860 HttpRequestInfo request;
861 request.method = "GET";
862 request.url = GURL("http://redirect.com/");
863 request.load_flags = 0;
864
[email protected]3fe8d2f82013-10-17 08:56:07865 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55866 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07867 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55868
869 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07870 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55871
[email protected]49639fa2011-12-20 23:22:41872 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55873
[email protected]49639fa2011-12-20 23:22:41874 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55875 EXPECT_EQ(ERR_IO_PENDING, rv);
876
877 EXPECT_EQ(OK, callback.WaitForResult());
878
879 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50880 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55881 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
882 std::string url;
883 EXPECT_TRUE(response->headers->IsRedirect(&url));
884 EXPECT_EQ("http://good.com/", url);
885}
886
[email protected]1628fe92011-10-04 23:04:55887// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02888TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55889 MockRead data_reads[] = {
890 MockRead("HTTP/1.1 302 Redirect\r\n"),
891 MockRead("Location: http://good.com/\r\n"),
892 MockRead("Location: http://evil.com/\r\n"),
893 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06894 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55895 };
896 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
897 arraysize(data_reads));
898 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
899}
900
[email protected]ef0faf2e72009-03-05 23:27:23901// Do a request using the HEAD method. Verify that we don't try to read the
902// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02903TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42904 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23905 request.method = "HEAD";
906 request.url = GURL("http://www.google.com/");
907 request.load_flags = 0;
908
[email protected]3fe8d2f82013-10-17 08:56:07909 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27910 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27912
[email protected]ef0faf2e72009-03-05 23:27:23913 MockWrite data_writes1[] = {
914 MockWrite("HEAD / HTTP/1.1\r\n"
915 "Host: www.google.com\r\n"
916 "Connection: keep-alive\r\n"
917 "Content-Length: 0\r\n\r\n"),
918 };
919 MockRead data_reads1[] = {
920 MockRead("HTTP/1.1 404 Not Found\r\n"),
921 MockRead("Server: Blah\r\n"),
922 MockRead("Content-Length: 1234\r\n\r\n"),
923
924 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06925 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23926 };
927
[email protected]31a2bfe2010-02-09 08:03:39928 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
929 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07930 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23931
[email protected]49639fa2011-12-20 23:22:41932 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23933
[email protected]49639fa2011-12-20 23:22:41934 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42935 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23936
937 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42938 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23939
[email protected]1c773ea12009-04-28 19:58:42940 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50941 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23942
943 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:50944 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23945 EXPECT_EQ(1234, response->headers->GetContentLength());
946 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
947
948 std::string server_header;
949 void* iter = NULL;
950 bool has_server_header = response->headers->EnumerateHeader(
951 &iter, "Server", &server_header);
952 EXPECT_TRUE(has_server_header);
953 EXPECT_EQ("Blah", server_header);
954
955 // Reading should give EOF right away, since there is no message body
956 // (despite non-zero content-length).
957 std::string response_data;
958 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42959 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23960 EXPECT_EQ("", response_data);
961}
962
[email protected]23e482282013-06-14 16:08:02963TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:07964 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:52965
966 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35967 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
968 MockRead("hello"),
969 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
970 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:06971 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:52972 };
[email protected]31a2bfe2010-02-09 08:03:39973 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07974 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52975
[email protected]0b0bf032010-09-21 18:08:50976 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:52977 "hello", "world"
978 };
979
980 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42981 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52982 request.method = "GET";
983 request.url = GURL("http://www.google.com/");
984 request.load_flags = 0;
985
[email protected]262eec82013-03-19 21:01:36986 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:50987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27988
[email protected]49639fa2011-12-20 23:22:41989 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52990
[email protected]49639fa2011-12-20 23:22:41991 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42992 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52993
994 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42995 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52996
[email protected]1c773ea12009-04-28 19:58:42997 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50998 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:52999
[email protected]90499482013-06-01 00:39:501000 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251001 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521002
1003 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571004 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421005 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251006 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521007 }
1008}
1009
[email protected]23e482282013-06-14 16:08:021010TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061011 ScopedVector<UploadElementReader> element_readers;
1012 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201013 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271014
[email protected]1c773ea12009-04-28 19:58:421015 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521016 request.method = "POST";
1017 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271018 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521019 request.load_flags = 0;
1020
[email protected]3fe8d2f82013-10-17 08:56:071021 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271022 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271024
initial.commit586acc5fe2008-07-26 22:42:521025 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351026 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1027 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1028 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061029 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521030 };
[email protected]31a2bfe2010-02-09 08:03:391031 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071032 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521033
[email protected]49639fa2011-12-20 23:22:411034 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521035
[email protected]49639fa2011-12-20 23:22:411036 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421037 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521038
1039 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421040 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521041
[email protected]1c773ea12009-04-28 19:58:421042 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501043 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521044
[email protected]90499482013-06-01 00:39:501045 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251046 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521047
1048 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571049 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421050 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251051 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521052}
1053
[email protected]3a2d3662009-03-27 03:49:141054// This test is almost the same as Ignores100 above, but the response contains
1055// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571056// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021057TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421058 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141059 request.method = "GET";
1060 request.url = GURL("http://www.foo.com/");
1061 request.load_flags = 0;
1062
[email protected]3fe8d2f82013-10-17 08:56:071063 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271064 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271066
[email protected]3a2d3662009-03-27 03:49:141067 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571068 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1069 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141070 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061071 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141072 };
[email protected]31a2bfe2010-02-09 08:03:391073 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071074 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141075
[email protected]49639fa2011-12-20 23:22:411076 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141077
[email protected]49639fa2011-12-20 23:22:411078 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421079 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141080
1081 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421082 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141083
[email protected]1c773ea12009-04-28 19:58:421084 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501085 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141086
[email protected]90499482013-06-01 00:39:501087 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141088 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1089
1090 std::string response_data;
1091 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421092 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141093 EXPECT_EQ("hello world", response_data);
1094}
1095
[email protected]23e482282013-06-14 16:08:021096TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381097 HttpRequestInfo request;
1098 request.method = "POST";
1099 request.url = GURL("http://www.foo.com/");
1100 request.load_flags = 0;
1101
[email protected]3fe8d2f82013-10-17 08:56:071102 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271103 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071104 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271105
[email protected]ee9410e72010-01-07 01:42:381106 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061107 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1108 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381109 };
[email protected]31a2bfe2010-02-09 08:03:391110 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071111 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381112
[email protected]49639fa2011-12-20 23:22:411113 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381114
[email protected]49639fa2011-12-20 23:22:411115 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381116 EXPECT_EQ(ERR_IO_PENDING, rv);
1117
1118 rv = callback.WaitForResult();
1119 EXPECT_EQ(OK, rv);
1120
1121 std::string response_data;
1122 rv = ReadTransaction(trans.get(), &response_data);
1123 EXPECT_EQ(OK, rv);
1124 EXPECT_EQ("", response_data);
1125}
1126
[email protected]23e482282013-06-14 16:08:021127TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381128 HttpRequestInfo request;
1129 request.method = "POST";
1130 request.url = GURL("http://www.foo.com/");
1131 request.load_flags = 0;
1132
[email protected]3fe8d2f82013-10-17 08:56:071133 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271134 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071135 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1136
[email protected]cb9bf6ca2011-01-28 13:15:271137
[email protected]ee9410e72010-01-07 01:42:381138 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061139 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381140 };
[email protected]31a2bfe2010-02-09 08:03:391141 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071142 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381143
[email protected]49639fa2011-12-20 23:22:411144 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381145
[email protected]49639fa2011-12-20 23:22:411146 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381147 EXPECT_EQ(ERR_IO_PENDING, rv);
1148
1149 rv = callback.WaitForResult();
1150 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1151}
1152
[email protected]23e482282013-06-14 16:08:021153void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511154 const MockWrite* write_failure,
1155 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421156 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521157 request.method = "GET";
1158 request.url = GURL("http://www.foo.com/");
1159 request.load_flags = 0;
1160
[email protected]58e32bb2013-01-21 18:23:251161 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071162 session_deps_.net_log = &net_log;
1163 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271164
[email protected]202965992011-12-07 23:04:511165 // Written data for successfully sending both requests.
1166 MockWrite data1_writes[] = {
1167 MockWrite("GET / HTTP/1.1\r\n"
1168 "Host: www.foo.com\r\n"
1169 "Connection: keep-alive\r\n\r\n"),
1170 MockWrite("GET / HTTP/1.1\r\n"
1171 "Host: www.foo.com\r\n"
1172 "Connection: keep-alive\r\n\r\n")
1173 };
1174
1175 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521176 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351177 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1178 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061179 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521180 };
[email protected]202965992011-12-07 23:04:511181
1182 if (write_failure) {
1183 ASSERT_TRUE(!read_failure);
1184 data1_writes[1] = *write_failure;
1185 } else {
1186 ASSERT_TRUE(read_failure);
1187 data1_reads[2] = *read_failure;
1188 }
1189
1190 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1191 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071192 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521193
1194 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351195 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1196 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061197 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521198 };
[email protected]31a2bfe2010-02-09 08:03:391199 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071200 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521201
1202 const char* kExpectedResponseData[] = {
1203 "hello", "world"
1204 };
1205
[email protected]58e32bb2013-01-21 18:23:251206 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521207 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411208 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521209
[email protected]262eec82013-03-19 21:01:361210 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521212
[email protected]49639fa2011-12-20 23:22:411213 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421214 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521215
1216 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421217 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521218
[email protected]58e32bb2013-01-21 18:23:251219 LoadTimingInfo load_timing_info;
1220 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1221 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1222 if (i == 0) {
1223 first_socket_log_id = load_timing_info.socket_log_id;
1224 } else {
1225 // The second request should be using a new socket.
1226 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1227 }
1228
[email protected]1c773ea12009-04-28 19:58:421229 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501230 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521231
[email protected]90499482013-06-01 00:39:501232 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251233 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521234
1235 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571236 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421237 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251238 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521239 }
1240}
[email protected]3d2a59b2008-09-26 19:44:251241
[email protected]23e482282013-06-14 16:08:021242TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231243 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061244 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511245 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1246}
1247
[email protected]23e482282013-06-14 16:08:021248TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061249 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511250 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251251}
1252
[email protected]23e482282013-06-14 16:08:021253TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061254 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511255 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251256}
1257
[email protected]23e482282013-06-14 16:08:021258TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421259 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251260 request.method = "GET";
1261 request.url = GURL("http://www.google.com/");
1262 request.load_flags = 0;
1263
[email protected]3fe8d2f82013-10-17 08:56:071264 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271265 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071266 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271267
[email protected]3d2a59b2008-09-26 19:44:251268 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061269 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351270 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1271 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061272 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251273 };
[email protected]31a2bfe2010-02-09 08:03:391274 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071275 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251276
[email protected]49639fa2011-12-20 23:22:411277 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251278
[email protected]49639fa2011-12-20 23:22:411279 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421280 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251281
1282 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421283 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251284
[email protected]1c773ea12009-04-28 19:58:421285 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251286 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251287}
1288
1289// What do various browsers do when the server closes a non-keepalive
1290// connection without sending any response header or body?
1291//
1292// IE7: error page
1293// Safari 3.1.2 (Windows): error page
1294// Firefox 3.0.1: blank page
1295// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421296// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1297// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021298TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251299 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061300 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351301 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1302 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061303 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251304 };
[email protected]31a2bfe2010-02-09 08:03:391305 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1306 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421307 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251308}
[email protected]038e9a32008-10-08 22:40:161309
[email protected]7a5378b2012-11-04 03:25:171310// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1311// tests. There was a bug causing HttpNetworkTransaction to hang in the
1312// destructor in such situations.
1313// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021314TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171315 HttpRequestInfo request;
1316 request.method = "GET";
1317 request.url = GURL("http://www.google.com/");
1318 request.load_flags = 0;
1319
[email protected]bb88e1d32013-05-03 23:11:071320 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361321 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171323
1324 MockRead data_reads[] = {
1325 MockRead("HTTP/1.0 200 OK\r\n"),
1326 MockRead("Connection: keep-alive\r\n"),
1327 MockRead("Content-Length: 100\r\n\r\n"),
1328 MockRead("hello"),
1329 MockRead(SYNCHRONOUS, 0),
1330 };
1331 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071332 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171333
1334 TestCompletionCallback callback;
1335
1336 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1337 EXPECT_EQ(ERR_IO_PENDING, rv);
1338
1339 rv = callback.WaitForResult();
1340 EXPECT_EQ(OK, rv);
1341
1342 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501343 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171344 if (rv == ERR_IO_PENDING)
1345 rv = callback.WaitForResult();
1346 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501347 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171348 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1349
1350 trans.reset();
[email protected]2da659e2013-05-23 20:51:341351 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171352 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1353}
1354
[email protected]23e482282013-06-14 16:08:021355TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171356 HttpRequestInfo request;
1357 request.method = "GET";
1358 request.url = GURL("http://www.google.com/");
1359 request.load_flags = 0;
1360
[email protected]bb88e1d32013-05-03 23:11:071361 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361362 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501363 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171364
1365 MockRead data_reads[] = {
1366 MockRead("HTTP/1.0 200 OK\r\n"),
1367 MockRead("Connection: keep-alive\r\n"),
1368 MockRead("Content-Length: 100\r\n\r\n"),
1369 MockRead(SYNCHRONOUS, 0),
1370 };
1371 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071372 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171373
1374 TestCompletionCallback callback;
1375
1376 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1377 EXPECT_EQ(ERR_IO_PENDING, rv);
1378
1379 rv = callback.WaitForResult();
1380 EXPECT_EQ(OK, rv);
1381
1382 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501383 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171384 if (rv == ERR_IO_PENDING)
1385 rv = callback.WaitForResult();
1386 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1387
1388 trans.reset();
[email protected]2da659e2013-05-23 20:51:341389 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171390 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1391}
1392
[email protected]0b0bf032010-09-21 18:08:501393// Test that we correctly reuse a keep-alive connection after not explicitly
1394// reading the body.
[email protected]23e482282013-06-14 16:08:021395TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131396 HttpRequestInfo request;
1397 request.method = "GET";
1398 request.url = GURL("http://www.foo.com/");
1399 request.load_flags = 0;
1400
[email protected]58e32bb2013-01-21 18:23:251401 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071402 session_deps_.net_log = &net_log;
1403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271404
[email protected]0b0bf032010-09-21 18:08:501405 // Note that because all these reads happen in the same
1406 // StaticSocketDataProvider, it shows that the same socket is being reused for
1407 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131408 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501409 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1410 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131411 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501412 MockRead("HTTP/1.1 302 Found\r\n"
1413 "Content-Length: 0\r\n\r\n"),
1414 MockRead("HTTP/1.1 302 Found\r\n"
1415 "Content-Length: 5\r\n\r\n"
1416 "hello"),
1417 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1418 "Content-Length: 0\r\n\r\n"),
1419 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1420 "Content-Length: 5\r\n\r\n"
1421 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131422 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1423 MockRead("hello"),
1424 };
1425 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071426 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131427
1428 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061429 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131430 };
1431 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071432 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131433
[email protected]0b0bf032010-09-21 18:08:501434 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1435 std::string response_lines[kNumUnreadBodies];
1436
[email protected]58e32bb2013-01-21 18:23:251437 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501438 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411439 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131440
[email protected]262eec82013-03-19 21:01:361441 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131443
[email protected]49639fa2011-12-20 23:22:411444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131445 EXPECT_EQ(ERR_IO_PENDING, rv);
1446
1447 rv = callback.WaitForResult();
1448 EXPECT_EQ(OK, rv);
1449
[email protected]58e32bb2013-01-21 18:23:251450 LoadTimingInfo load_timing_info;
1451 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1452 if (i == 0) {
1453 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1454 first_socket_log_id = load_timing_info.socket_log_id;
1455 } else {
1456 TestLoadTimingReused(load_timing_info);
1457 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1458 }
1459
[email protected]fc31d6a42010-06-24 18:05:131460 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501461 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131462
[email protected]90499482013-06-01 00:39:501463 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501464 response_lines[i] = response->headers->GetStatusLine();
1465
1466 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131467 }
[email protected]0b0bf032010-09-21 18:08:501468
1469 const char* const kStatusLines[] = {
1470 "HTTP/1.1 204 No Content",
1471 "HTTP/1.1 205 Reset Content",
1472 "HTTP/1.1 304 Not Modified",
1473 "HTTP/1.1 302 Found",
1474 "HTTP/1.1 302 Found",
1475 "HTTP/1.1 301 Moved Permanently",
1476 "HTTP/1.1 301 Moved Permanently",
1477 };
1478
1479 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1480 forgot_to_update_kStatusLines);
1481
1482 for (int i = 0; i < kNumUnreadBodies; ++i)
1483 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1484
[email protected]49639fa2011-12-20 23:22:411485 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361486 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411488 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501489 EXPECT_EQ(ERR_IO_PENDING, rv);
1490 rv = callback.WaitForResult();
1491 EXPECT_EQ(OK, rv);
1492 const HttpResponseInfo* response = trans->GetResponseInfo();
1493 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501494 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501495 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1496 std::string response_data;
1497 rv = ReadTransaction(trans.get(), &response_data);
1498 EXPECT_EQ(OK, rv);
1499 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131500}
1501
[email protected]038e9a32008-10-08 22:40:161502// Test the request-challenge-retry sequence for basic auth.
1503// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021504TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421505 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161506 request.method = "GET";
1507 request.url = GURL("http://www.google.com/");
1508 request.load_flags = 0;
1509
[email protected]58e32bb2013-01-21 18:23:251510 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071511 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071512 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271513 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071514 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271515
[email protected]f9ee6b52008-11-08 06:46:231516 MockWrite data_writes1[] = {
1517 MockWrite("GET / HTTP/1.1\r\n"
1518 "Host: www.google.com\r\n"
1519 "Connection: keep-alive\r\n\r\n"),
1520 };
1521
[email protected]038e9a32008-10-08 22:40:161522 MockRead data_reads1[] = {
1523 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1524 // Give a couple authenticate options (only the middle one is actually
1525 // supported).
[email protected]22927ad2009-09-21 19:56:191526 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161527 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1528 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1529 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1530 // Large content-length -- won't matter, as connection will be reset.
1531 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061532 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161533 };
1534
1535 // After calling trans->RestartWithAuth(), this is the request we should
1536 // be issuing -- the final header line contains the credentials.
1537 MockWrite data_writes2[] = {
1538 MockWrite("GET / HTTP/1.1\r\n"
1539 "Host: www.google.com\r\n"
1540 "Connection: keep-alive\r\n"
1541 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1542 };
1543
1544 // Lastly, the server responds with the actual content.
1545 MockRead data_reads2[] = {
1546 MockRead("HTTP/1.0 200 OK\r\n"),
1547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1548 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061549 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161550 };
1551
[email protected]31a2bfe2010-02-09 08:03:391552 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1553 data_writes1, arraysize(data_writes1));
1554 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1555 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071556 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1557 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161558
[email protected]49639fa2011-12-20 23:22:411559 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161560
[email protected]49639fa2011-12-20 23:22:411561 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421562 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161563
1564 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421565 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161566
[email protected]58e32bb2013-01-21 18:23:251567 LoadTimingInfo load_timing_info1;
1568 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1569 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1570
[email protected]1c773ea12009-04-28 19:58:421571 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501572 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041573 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161574
[email protected]49639fa2011-12-20 23:22:411575 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161576
[email protected]49639fa2011-12-20 23:22:411577 rv = trans->RestartWithAuth(
1578 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421579 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161580
1581 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421582 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161583
[email protected]58e32bb2013-01-21 18:23:251584 LoadTimingInfo load_timing_info2;
1585 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1586 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1587 // The load timing after restart should have a new socket ID, and times after
1588 // those of the first load timing.
1589 EXPECT_LE(load_timing_info1.receive_headers_end,
1590 load_timing_info2.connect_timing.connect_start);
1591 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1592
[email protected]038e9a32008-10-08 22:40:161593 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501594 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161595 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1596 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161597}
1598
[email protected]23e482282013-06-14 16:08:021599TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461600 HttpRequestInfo request;
1601 request.method = "GET";
1602 request.url = GURL("http://www.google.com/");
1603 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1604
[email protected]3fe8d2f82013-10-17 08:56:071605 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271606 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271608
[email protected]861fcd52009-08-26 02:33:461609 MockWrite data_writes[] = {
1610 MockWrite("GET / HTTP/1.1\r\n"
1611 "Host: www.google.com\r\n"
1612 "Connection: keep-alive\r\n\r\n"),
1613 };
1614
1615 MockRead data_reads[] = {
1616 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1617 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1618 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1619 // Large content-length -- won't matter, as connection will be reset.
1620 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061621 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461622 };
1623
[email protected]31a2bfe2010-02-09 08:03:391624 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1625 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071626 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411627 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461628
[email protected]49639fa2011-12-20 23:22:411629 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461630 EXPECT_EQ(ERR_IO_PENDING, rv);
1631
1632 rv = callback.WaitForResult();
1633 EXPECT_EQ(0, rv);
1634
1635 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501636 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461637 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1638}
1639
[email protected]2d2697f92009-02-18 21:00:321640// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1641// connection.
[email protected]23e482282013-06-14 16:08:021642TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421643 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321644 request.method = "GET";
1645 request.url = GURL("http://www.google.com/");
1646 request.load_flags = 0;
1647
[email protected]58e32bb2013-01-21 18:23:251648 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071649 session_deps_.net_log = &log;
1650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271651
[email protected]2d2697f92009-02-18 21:00:321652 MockWrite data_writes1[] = {
1653 MockWrite("GET / HTTP/1.1\r\n"
1654 "Host: www.google.com\r\n"
1655 "Connection: keep-alive\r\n\r\n"),
1656
1657 // After calling trans->RestartWithAuth(), this is the request we should
1658 // be issuing -- the final header line contains the credentials.
1659 MockWrite("GET / HTTP/1.1\r\n"
1660 "Host: www.google.com\r\n"
1661 "Connection: keep-alive\r\n"
1662 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1663 };
1664
1665 MockRead data_reads1[] = {
1666 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1667 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1668 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1669 MockRead("Content-Length: 14\r\n\r\n"),
1670 MockRead("Unauthorized\r\n"),
1671
1672 // Lastly, the server responds with the actual content.
1673 MockRead("HTTP/1.1 200 OK\r\n"),
1674 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501675 MockRead("Content-Length: 5\r\n\r\n"),
1676 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321677 };
1678
[email protected]2d0a4f92011-05-05 16:38:461679 // If there is a regression where we disconnect a Keep-Alive
1680 // connection during an auth roundtrip, we'll end up reading this.
1681 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061682 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461683 };
1684
[email protected]31a2bfe2010-02-09 08:03:391685 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1686 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461687 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1688 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071689 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1690 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321691
[email protected]49639fa2011-12-20 23:22:411692 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321693
[email protected]262eec82013-03-19 21:01:361694 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411696 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421697 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321698
1699 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421700 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321701
[email protected]58e32bb2013-01-21 18:23:251702 LoadTimingInfo load_timing_info1;
1703 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1704 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1705
[email protected]1c773ea12009-04-28 19:58:421706 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501707 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041708 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321709
[email protected]49639fa2011-12-20 23:22:411710 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321711
[email protected]49639fa2011-12-20 23:22:411712 rv = trans->RestartWithAuth(
1713 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421714 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321715
1716 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421717 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321718
[email protected]58e32bb2013-01-21 18:23:251719 LoadTimingInfo load_timing_info2;
1720 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1721 TestLoadTimingReused(load_timing_info2);
1722 // The load timing after restart should have the same socket ID, and times
1723 // those of the first load timing.
1724 EXPECT_LE(load_timing_info1.receive_headers_end,
1725 load_timing_info2.send_start);
1726 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1727
[email protected]2d2697f92009-02-18 21:00:321728 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501729 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321730 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501731 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321732}
1733
1734// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1735// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021736TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421737 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321738 request.method = "GET";
1739 request.url = GURL("http://www.google.com/");
1740 request.load_flags = 0;
1741
[email protected]bb88e1d32013-05-03 23:11:071742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271743
[email protected]2d2697f92009-02-18 21:00:321744 MockWrite data_writes1[] = {
1745 MockWrite("GET / HTTP/1.1\r\n"
1746 "Host: www.google.com\r\n"
1747 "Connection: keep-alive\r\n\r\n"),
1748
1749 // After calling trans->RestartWithAuth(), this is the request we should
1750 // be issuing -- the final header line contains the credentials.
1751 MockWrite("GET / HTTP/1.1\r\n"
1752 "Host: www.google.com\r\n"
1753 "Connection: keep-alive\r\n"
1754 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1755 };
1756
[email protected]2d2697f92009-02-18 21:00:321757 MockRead data_reads1[] = {
1758 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1759 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311760 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321761
1762 // Lastly, the server responds with the actual content.
1763 MockRead("HTTP/1.1 200 OK\r\n"),
1764 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501765 MockRead("Content-Length: 5\r\n\r\n"),
1766 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321767 };
1768
[email protected]2d0a4f92011-05-05 16:38:461769 // An incorrect reconnect would cause this to be read.
1770 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061771 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461772 };
1773
[email protected]31a2bfe2010-02-09 08:03:391774 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1775 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461776 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1777 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071778 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1779 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321780
[email protected]49639fa2011-12-20 23:22:411781 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321782
[email protected]262eec82013-03-19 21:01:361783 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411785 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421786 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321787
1788 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421789 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321790
[email protected]1c773ea12009-04-28 19:58:421791 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501792 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041793 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321794
[email protected]49639fa2011-12-20 23:22:411795 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321796
[email protected]49639fa2011-12-20 23:22:411797 rv = trans->RestartWithAuth(
1798 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421799 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321800
1801 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421802 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321803
1804 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501805 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321806 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501807 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321808}
1809
1810// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1811// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:021812TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421813 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321814 request.method = "GET";
1815 request.url = GURL("http://www.google.com/");
1816 request.load_flags = 0;
1817
[email protected]bb88e1d32013-05-03 23:11:071818 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271819
[email protected]2d2697f92009-02-18 21:00:321820 MockWrite data_writes1[] = {
1821 MockWrite("GET / HTTP/1.1\r\n"
1822 "Host: www.google.com\r\n"
1823 "Connection: keep-alive\r\n\r\n"),
1824
1825 // After calling trans->RestartWithAuth(), this is the request we should
1826 // be issuing -- the final header line contains the credentials.
1827 MockWrite("GET / HTTP/1.1\r\n"
1828 "Host: www.google.com\r\n"
1829 "Connection: keep-alive\r\n"
1830 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1831 };
1832
1833 // Respond with 5 kb of response body.
1834 std::string large_body_string("Unauthorized");
1835 large_body_string.append(5 * 1024, ' ');
1836 large_body_string.append("\r\n");
1837
1838 MockRead data_reads1[] = {
1839 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1840 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1841 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1842 // 5134 = 12 + 5 * 1024 + 2
1843 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061844 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:321845
1846 // Lastly, the server responds with the actual content.
1847 MockRead("HTTP/1.1 200 OK\r\n"),
1848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501849 MockRead("Content-Length: 5\r\n\r\n"),
1850 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321851 };
1852
[email protected]2d0a4f92011-05-05 16:38:461853 // An incorrect reconnect would cause this to be read.
1854 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061855 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461856 };
1857
[email protected]31a2bfe2010-02-09 08:03:391858 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1859 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461860 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1861 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071862 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1863 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321864
[email protected]49639fa2011-12-20 23:22:411865 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321866
[email protected]262eec82013-03-19 21:01:361867 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411869 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421870 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321871
1872 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421873 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321874
[email protected]1c773ea12009-04-28 19:58:421875 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501876 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041877 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321878
[email protected]49639fa2011-12-20 23:22:411879 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321880
[email protected]49639fa2011-12-20 23:22:411881 rv = trans->RestartWithAuth(
1882 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421883 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321884
1885 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421886 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321887
1888 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501889 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321890 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501891 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321892}
1893
1894// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:311895// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:021896TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:311897 HttpRequestInfo request;
1898 request.method = "GET";
1899 request.url = GURL("http://www.google.com/");
1900 request.load_flags = 0;
1901
[email protected]bb88e1d32013-05-03 23:11:071902 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271903
[email protected]11203f012009-11-12 23:02:311904 MockWrite data_writes1[] = {
1905 MockWrite("GET / HTTP/1.1\r\n"
1906 "Host: www.google.com\r\n"
1907 "Connection: keep-alive\r\n\r\n"),
1908 // This simulates the seemingly successful write to a closed connection
1909 // if the bug is not fixed.
1910 MockWrite("GET / HTTP/1.1\r\n"
1911 "Host: www.google.com\r\n"
1912 "Connection: keep-alive\r\n"
1913 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1914 };
1915
1916 MockRead data_reads1[] = {
1917 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1918 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1919 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1920 MockRead("Content-Length: 14\r\n\r\n"),
1921 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:061922 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:311923 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:061924 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:311925 };
1926
1927 // After calling trans->RestartWithAuth(), this is the request we should
1928 // be issuing -- the final header line contains the credentials.
1929 MockWrite data_writes2[] = {
1930 MockWrite("GET / HTTP/1.1\r\n"
1931 "Host: www.google.com\r\n"
1932 "Connection: keep-alive\r\n"
1933 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1934 };
1935
1936 // Lastly, the server responds with the actual content.
1937 MockRead data_reads2[] = {
1938 MockRead("HTTP/1.1 200 OK\r\n"),
1939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501940 MockRead("Content-Length: 5\r\n\r\n"),
1941 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:311942 };
1943
[email protected]31a2bfe2010-02-09 08:03:391944 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1945 data_writes1, arraysize(data_writes1));
1946 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1947 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071948 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1949 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:311950
[email protected]49639fa2011-12-20 23:22:411951 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:311952
[email protected]262eec82013-03-19 21:01:361953 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501954 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411955 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:311956 EXPECT_EQ(ERR_IO_PENDING, rv);
1957
1958 rv = callback1.WaitForResult();
1959 EXPECT_EQ(OK, rv);
1960
1961 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501962 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041963 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:311964
[email protected]49639fa2011-12-20 23:22:411965 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:311966
[email protected]49639fa2011-12-20 23:22:411967 rv = trans->RestartWithAuth(
1968 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:311969 EXPECT_EQ(ERR_IO_PENDING, rv);
1970
1971 rv = callback2.WaitForResult();
1972 EXPECT_EQ(OK, rv);
1973
1974 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501975 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:311976 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501977 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:311978}
1979
[email protected]394816e92010-08-03 07:38:591980// Test the request-challenge-retry sequence for basic auth, over a connection
1981// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:021982TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:591983 HttpRequestInfo request;
1984 request.method = "GET";
1985 request.url = GURL("https://www.google.com/");
1986 // when the no authentication data flag is set.
1987 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1988
[email protected]cb9bf6ca2011-01-28 13:15:271989 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:071990 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:201991 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:291992 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071993 session_deps_.net_log = log.bound().net_log();
1994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271995
[email protected]394816e92010-08-03 07:38:591996 // Since we have proxy, should try to establish tunnel.
1997 MockWrite data_writes1[] = {
1998 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1999 "Host: www.google.com\r\n"
2000 "Proxy-Connection: keep-alive\r\n\r\n"),
2001
2002 // After calling trans->RestartWithAuth(), this is the request we should
2003 // be issuing -- the final header line contains the credentials.
2004 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2005 "Host: www.google.com\r\n"
2006 "Proxy-Connection: keep-alive\r\n"
2007 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2008
2009 MockWrite("GET / HTTP/1.1\r\n"
2010 "Host: www.google.com\r\n"
2011 "Connection: keep-alive\r\n\r\n"),
2012 };
2013
2014 // The proxy responds to the connect with a 407, using a persistent
2015 // connection.
2016 MockRead data_reads1[] = {
2017 // No credentials.
2018 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2019 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2020 MockRead("Proxy-Connection: close\r\n\r\n"),
2021
2022 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2023
2024 MockRead("HTTP/1.1 200 OK\r\n"),
2025 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502026 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062027 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592028 };
2029
2030 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2031 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072032 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062033 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072034 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592035
[email protected]49639fa2011-12-20 23:22:412036 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592037
[email protected]262eec82013-03-19 21:01:362038 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502039 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502040
[email protected]49639fa2011-12-20 23:22:412041 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592042 EXPECT_EQ(ERR_IO_PENDING, rv);
2043
2044 rv = callback1.WaitForResult();
2045 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572046 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402047 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592048 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402049 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592050 NetLog::PHASE_NONE);
2051 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402052 entries, pos,
[email protected]394816e92010-08-03 07:38:592053 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2054 NetLog::PHASE_NONE);
2055
2056 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502057 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502058 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592059 EXPECT_EQ(407, response->headers->response_code());
2060 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042061 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592062
[email protected]029c83b62013-01-24 05:28:202063 LoadTimingInfo load_timing_info;
2064 // CONNECT requests and responses are handled at the connect job level, so
2065 // the transaction does not yet have a connection.
2066 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2067
[email protected]49639fa2011-12-20 23:22:412068 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592069
[email protected]49639fa2011-12-20 23:22:412070 rv = trans->RestartWithAuth(
2071 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592072 EXPECT_EQ(ERR_IO_PENDING, rv);
2073
2074 rv = callback2.WaitForResult();
2075 EXPECT_EQ(OK, rv);
2076
2077 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502078 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592079
2080 EXPECT_TRUE(response->headers->IsKeepAlive());
2081 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502082 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592083 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2084
2085 // The password prompt info should not be set.
2086 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502087
[email protected]029c83b62013-01-24 05:28:202088 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2089 TestLoadTimingNotReusedWithPac(load_timing_info,
2090 CONNECT_TIMING_HAS_SSL_TIMES);
2091
[email protected]0b0bf032010-09-21 18:08:502092 trans.reset();
[email protected]102e27c2011-02-23 01:01:312093 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592094}
2095
[email protected]11203f012009-11-12 23:02:312096// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322097// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022098TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272099 HttpRequestInfo request;
2100 request.method = "GET";
2101 request.url = GURL("https://www.google.com/");
2102 // Ensure that proxy authentication is attempted even
2103 // when the no authentication data flag is set.
2104 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2105
[email protected]2d2697f92009-02-18 21:00:322106 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072107 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292108 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072109 session_deps_.net_log = log.bound().net_log();
2110 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322111
[email protected]262eec82013-03-19 21:01:362112 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322114
[email protected]2d2697f92009-02-18 21:00:322115 // Since we have proxy, should try to establish tunnel.
2116 MockWrite data_writes1[] = {
2117 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452118 "Host: www.google.com\r\n"
2119 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322120
2121 // After calling trans->RestartWithAuth(), this is the request we should
2122 // be issuing -- the final header line contains the credentials.
2123 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2124 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452125 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322126 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2127 };
2128
2129 // The proxy responds to the connect with a 407, using a persistent
2130 // connection.
2131 MockRead data_reads1[] = {
2132 // No credentials.
2133 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2134 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2135 MockRead("Content-Length: 10\r\n\r\n"),
2136 MockRead("0123456789"),
2137
2138 // Wrong credentials (wrong password).
2139 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2140 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2141 MockRead("Content-Length: 10\r\n\r\n"),
2142 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062143 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322144 };
2145
[email protected]31a2bfe2010-02-09 08:03:392146 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2147 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072148 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322149
[email protected]49639fa2011-12-20 23:22:412150 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322151
[email protected]49639fa2011-12-20 23:22:412152 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422153 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322154
2155 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422156 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572157 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402158 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392159 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402160 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392161 NetLog::PHASE_NONE);
2162 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402163 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392164 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2165 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322166
[email protected]1c773ea12009-04-28 19:58:422167 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502168 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502169 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322170 EXPECT_TRUE(response->headers->IsKeepAlive());
2171 EXPECT_EQ(407, response->headers->response_code());
2172 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422173 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042174 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322175
[email protected]49639fa2011-12-20 23:22:412176 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322177
2178 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412179 rv = trans->RestartWithAuth(
2180 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422181 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322182
2183 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422184 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322185
2186 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502187 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502188 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322189 EXPECT_TRUE(response->headers->IsKeepAlive());
2190 EXPECT_EQ(407, response->headers->response_code());
2191 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422192 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042193 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132194
[email protected]e60e47a2010-07-14 03:37:182195 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2196 // out of scope.
[email protected]102e27c2011-02-23 01:01:312197 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322198}
2199
[email protected]a8e9b162009-03-12 00:06:442200// Test that we don't read the response body when we fail to establish a tunnel,
2201// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022202TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272203 HttpRequestInfo request;
2204 request.method = "GET";
2205 request.url = GURL("https://www.google.com/");
2206 request.load_flags = 0;
2207
[email protected]a8e9b162009-03-12 00:06:442208 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072209 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442210
[email protected]bb88e1d32013-05-03 23:11:072211 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442212
[email protected]262eec82013-03-19 21:01:362213 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442215
[email protected]a8e9b162009-03-12 00:06:442216 // Since we have proxy, should try to establish tunnel.
2217 MockWrite data_writes[] = {
2218 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452219 "Host: www.google.com\r\n"
2220 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442221 };
2222
2223 // The proxy responds to the connect with a 407.
2224 MockRead data_reads[] = {
2225 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2226 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2227 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062228 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442229 };
2230
[email protected]31a2bfe2010-02-09 08:03:392231 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2232 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072233 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442234
[email protected]49639fa2011-12-20 23:22:412235 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442236
[email protected]49639fa2011-12-20 23:22:412237 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422238 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442239
2240 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422241 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442242
[email protected]1c773ea12009-04-28 19:58:422243 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502244 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442245
2246 EXPECT_TRUE(response->headers->IsKeepAlive());
2247 EXPECT_EQ(407, response->headers->response_code());
2248 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422249 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442250
2251 std::string response_data;
2252 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422253 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182254
2255 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312256 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442257}
2258
[email protected]8fdbcd22010-05-05 02:54:522259// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2260// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022261TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522262 HttpRequestInfo request;
2263 request.method = "GET";
2264 request.url = GURL("http://www.google.com/");
2265 request.load_flags = 0;
2266
[email protected]cb9bf6ca2011-01-28 13:15:272267 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072268 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272269 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272271
[email protected]8fdbcd22010-05-05 02:54:522272 MockWrite data_writes1[] = {
2273 MockWrite("GET / HTTP/1.1\r\n"
2274 "Host: www.google.com\r\n"
2275 "Connection: keep-alive\r\n\r\n"),
2276 };
2277
2278 MockRead data_reads1[] = {
2279 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2280 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2281 // Large content-length -- won't matter, as connection will be reset.
2282 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062283 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522284 };
2285
2286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2287 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072288 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522289
[email protected]49639fa2011-12-20 23:22:412290 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522291
[email protected]49639fa2011-12-20 23:22:412292 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522293 EXPECT_EQ(ERR_IO_PENDING, rv);
2294
2295 rv = callback.WaitForResult();
2296 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2297}
2298
[email protected]7a67a8152010-11-05 18:31:102299// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2300// through a non-authenticating proxy. The request should fail with
2301// ERR_UNEXPECTED_PROXY_AUTH.
2302// Note that it is impossible to detect if an HTTP server returns a 407 through
2303// a non-authenticating proxy - there is nothing to indicate whether the
2304// response came from the proxy or the server, so it is treated as if the proxy
2305// issued the challenge.
[email protected]23e482282013-06-14 16:08:022306TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232307 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272308 HttpRequestInfo request;
2309 request.method = "GET";
2310 request.url = GURL("https://www.google.com/");
2311
[email protected]bb88e1d32013-05-03 23:11:072312 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292313 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072314 session_deps_.net_log = log.bound().net_log();
2315 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102316
[email protected]7a67a8152010-11-05 18:31:102317 // Since we have proxy, should try to establish tunnel.
2318 MockWrite data_writes1[] = {
2319 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2320 "Host: www.google.com\r\n"
2321 "Proxy-Connection: keep-alive\r\n\r\n"),
2322
2323 MockWrite("GET / HTTP/1.1\r\n"
2324 "Host: www.google.com\r\n"
2325 "Connection: keep-alive\r\n\r\n"),
2326 };
2327
2328 MockRead data_reads1[] = {
2329 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2330
2331 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2332 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2333 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062334 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102335 };
2336
2337 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2338 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072339 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062340 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102342
[email protected]49639fa2011-12-20 23:22:412343 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102344
[email protected]262eec82013-03-19 21:01:362345 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502346 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102347
[email protected]49639fa2011-12-20 23:22:412348 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102349 EXPECT_EQ(ERR_IO_PENDING, rv);
2350
2351 rv = callback1.WaitForResult();
2352 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572353 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402354 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102355 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402356 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102357 NetLog::PHASE_NONE);
2358 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402359 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102360 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2361 NetLog::PHASE_NONE);
2362}
[email protected]2df19bb2010-08-25 20:13:462363
[email protected]029c83b62013-01-24 05:28:202364// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022365TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202366 HttpRequestInfo request1;
2367 request1.method = "GET";
2368 request1.url = GURL("https://www.google.com/1");
2369
2370 HttpRequestInfo request2;
2371 request2.method = "GET";
2372 request2.url = GURL("https://www.google.com/2");
2373
2374 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072375 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202376 ProxyService::CreateFixed("PROXY myproxy:70"));
2377 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072378 session_deps_.net_log = log.bound().net_log();
2379 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202380
2381 // Since we have proxy, should try to establish tunnel.
2382 MockWrite data_writes1[] = {
2383 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2384 "Host: www.google.com\r\n"
2385 "Proxy-Connection: keep-alive\r\n\r\n"),
2386
2387 MockWrite("GET /1 HTTP/1.1\r\n"
2388 "Host: www.google.com\r\n"
2389 "Connection: keep-alive\r\n\r\n"),
2390
2391 MockWrite("GET /2 HTTP/1.1\r\n"
2392 "Host: www.google.com\r\n"
2393 "Connection: keep-alive\r\n\r\n"),
2394 };
2395
2396 // The proxy responds to the connect with a 407, using a persistent
2397 // connection.
2398 MockRead data_reads1[] = {
2399 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2400
2401 MockRead("HTTP/1.1 200 OK\r\n"),
2402 MockRead("Content-Length: 1\r\n\r\n"),
2403 MockRead(SYNCHRONOUS, "1"),
2404
2405 MockRead("HTTP/1.1 200 OK\r\n"),
2406 MockRead("Content-Length: 2\r\n\r\n"),
2407 MockRead(SYNCHRONOUS, "22"),
2408 };
2409
2410 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2411 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072412 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202413 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072414 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202415
2416 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362417 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502418 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202419
2420 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2421 EXPECT_EQ(ERR_IO_PENDING, rv);
2422
2423 rv = callback1.WaitForResult();
2424 EXPECT_EQ(OK, rv);
2425
2426 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2427 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502428 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202429 EXPECT_EQ(1, response1->headers->GetContentLength());
2430
2431 LoadTimingInfo load_timing_info1;
2432 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2433 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2434
2435 trans1.reset();
2436
2437 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362438 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502439 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202440
2441 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2442 EXPECT_EQ(ERR_IO_PENDING, rv);
2443
2444 rv = callback2.WaitForResult();
2445 EXPECT_EQ(OK, rv);
2446
2447 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2448 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502449 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202450 EXPECT_EQ(2, response2->headers->GetContentLength());
2451
2452 LoadTimingInfo load_timing_info2;
2453 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2454 TestLoadTimingReused(load_timing_info2);
2455
2456 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2457
2458 trans2.reset();
2459 session->CloseAllConnections();
2460}
2461
2462// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022463TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202464 HttpRequestInfo request1;
2465 request1.method = "GET";
2466 request1.url = GURL("https://www.google.com/1");
2467
2468 HttpRequestInfo request2;
2469 request2.method = "GET";
2470 request2.url = GURL("https://www.google.com/2");
2471
2472 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072473 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202474 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2475 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072476 session_deps_.net_log = log.bound().net_log();
2477 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202478
2479 // Since we have proxy, should try to establish tunnel.
2480 MockWrite data_writes1[] = {
2481 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2482 "Host: www.google.com\r\n"
2483 "Proxy-Connection: keep-alive\r\n\r\n"),
2484
2485 MockWrite("GET /1 HTTP/1.1\r\n"
2486 "Host: www.google.com\r\n"
2487 "Connection: keep-alive\r\n\r\n"),
2488
2489 MockWrite("GET /2 HTTP/1.1\r\n"
2490 "Host: www.google.com\r\n"
2491 "Connection: keep-alive\r\n\r\n"),
2492 };
2493
2494 // The proxy responds to the connect with a 407, using a persistent
2495 // connection.
2496 MockRead data_reads1[] = {
2497 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2498
2499 MockRead("HTTP/1.1 200 OK\r\n"),
2500 MockRead("Content-Length: 1\r\n\r\n"),
2501 MockRead(SYNCHRONOUS, "1"),
2502
2503 MockRead("HTTP/1.1 200 OK\r\n"),
2504 MockRead("Content-Length: 2\r\n\r\n"),
2505 MockRead(SYNCHRONOUS, "22"),
2506 };
2507
2508 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2509 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072510 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202511 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202513
2514 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362515 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502516 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202517
2518 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2519 EXPECT_EQ(ERR_IO_PENDING, rv);
2520
2521 rv = callback1.WaitForResult();
2522 EXPECT_EQ(OK, rv);
2523
2524 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2525 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502526 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202527 EXPECT_EQ(1, response1->headers->GetContentLength());
2528
2529 LoadTimingInfo load_timing_info1;
2530 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2531 TestLoadTimingNotReusedWithPac(load_timing_info1,
2532 CONNECT_TIMING_HAS_SSL_TIMES);
2533
2534 trans1.reset();
2535
2536 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362537 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502538 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202539
2540 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2541 EXPECT_EQ(ERR_IO_PENDING, rv);
2542
2543 rv = callback2.WaitForResult();
2544 EXPECT_EQ(OK, rv);
2545
2546 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2547 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502548 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202549 EXPECT_EQ(2, response2->headers->GetContentLength());
2550
2551 LoadTimingInfo load_timing_info2;
2552 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2553 TestLoadTimingReusedWithPac(load_timing_info2);
2554
2555 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2556
2557 trans2.reset();
2558 session->CloseAllConnections();
2559}
2560
[email protected]2df19bb2010-08-25 20:13:462561// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022562TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272563 HttpRequestInfo request;
2564 request.method = "GET";
2565 request.url = GURL("http://www.google.com/");
2566
[email protected]2df19bb2010-08-25 20:13:462567 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072568 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112569 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292570 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072571 session_deps_.net_log = log.bound().net_log();
2572 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462573
[email protected]2df19bb2010-08-25 20:13:462574 // Since we have proxy, should use full url
2575 MockWrite data_writes1[] = {
2576 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2577 "Host: www.google.com\r\n"
2578 "Proxy-Connection: keep-alive\r\n\r\n"),
2579 };
2580
2581 MockRead data_reads1[] = {
2582 MockRead("HTTP/1.1 200 OK\r\n"),
2583 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2584 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062585 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462586 };
2587
2588 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2589 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072590 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062591 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462593
[email protected]49639fa2011-12-20 23:22:412594 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462595
[email protected]262eec82013-03-19 21:01:362596 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502597 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502598
[email protected]49639fa2011-12-20 23:22:412599 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462600 EXPECT_EQ(ERR_IO_PENDING, rv);
2601
2602 rv = callback1.WaitForResult();
2603 EXPECT_EQ(OK, rv);
2604
[email protected]58e32bb2013-01-21 18:23:252605 LoadTimingInfo load_timing_info;
2606 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2607 TestLoadTimingNotReused(load_timing_info,
2608 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2609
[email protected]2df19bb2010-08-25 20:13:462610 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502611 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462612
2613 EXPECT_TRUE(response->headers->IsKeepAlive());
2614 EXPECT_EQ(200, response->headers->response_code());
2615 EXPECT_EQ(100, response->headers->GetContentLength());
2616 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2617
2618 // The password prompt info should not be set.
2619 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2620}
2621
[email protected]7642b5ae2010-09-01 20:55:172622// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022623TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272624 HttpRequestInfo request;
2625 request.method = "GET";
2626 request.url = GURL("http://www.google.com/");
2627 request.load_flags = 0;
2628
[email protected]7642b5ae2010-09-01 20:55:172629 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072630 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112631 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292632 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072633 session_deps_.net_log = log.bound().net_log();
2634 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172635
[email protected]7642b5ae2010-09-01 20:55:172636 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462637 scoped_ptr<SpdyFrame> req(
2638 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172639 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2640
[email protected]23e482282013-06-14 16:08:022641 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2642 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172643 MockRead spdy_reads[] = {
2644 CreateMockRead(*resp),
2645 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062646 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172647 };
2648
[email protected]dd54bd82012-07-19 23:44:572649 DelayedSocketData spdy_data(
2650 1, // wait for one write to finish before reading.
2651 spdy_reads, arraysize(spdy_reads),
2652 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072653 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172654
[email protected]8ddf8322012-02-23 18:08:062655 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022656 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172658
[email protected]49639fa2011-12-20 23:22:412659 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172660
[email protected]262eec82013-03-19 21:01:362661 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502663
[email protected]49639fa2011-12-20 23:22:412664 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172665 EXPECT_EQ(ERR_IO_PENDING, rv);
2666
2667 rv = callback1.WaitForResult();
2668 EXPECT_EQ(OK, rv);
2669
[email protected]58e32bb2013-01-21 18:23:252670 LoadTimingInfo load_timing_info;
2671 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2672 TestLoadTimingNotReused(load_timing_info,
2673 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2674
[email protected]7642b5ae2010-09-01 20:55:172675 const HttpResponseInfo* response = trans->GetResponseInfo();
2676 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502677 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172678 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2679
2680 std::string response_data;
2681 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232682 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172683}
2684
[email protected]dc7bd1c52010-11-12 00:01:132685// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022686TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272687 HttpRequestInfo request;
2688 request.method = "GET";
2689 request.url = GURL("http://www.google.com/");
2690 request.load_flags = 0;
2691
[email protected]79cb5c12011-09-12 13:12:042692 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072693 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042694 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292695 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072696 session_deps_.net_log = log.bound().net_log();
2697 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132698
[email protected]dc7bd1c52010-11-12 00:01:132699 // The first request will be a bare GET, the second request will be a
2700 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192701 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462702 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132703 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462704 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132705 };
[email protected]ff98d7f02012-03-22 21:44:192706 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462707 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2708 arraysize(kExtraAuthorizationHeaders) / 2,
2709 false,
2710 3,
2711 LOWEST,
2712 false));
[email protected]dc7bd1c52010-11-12 00:01:132713 MockWrite spdy_writes[] = {
2714 CreateMockWrite(*req_get, 1),
2715 CreateMockWrite(*req_get_authorization, 4),
2716 };
2717
2718 // The first response is a 407 proxy authentication challenge, and the second
2719 // response will be a 200 response since the second request includes a valid
2720 // Authorization header.
2721 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462722 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132723 };
[email protected]ff98d7f02012-03-22 21:44:192724 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022725 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132726 "407 Proxy Authentication Required",
2727 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2728 1));
[email protected]ff98d7f02012-03-22 21:44:192729 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022730 spdy_util_.ConstructSpdyBodyFrame(1, true));
2731 scoped_ptr<SpdyFrame> resp_data(
2732 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2733 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132734 MockRead spdy_reads[] = {
2735 CreateMockRead(*resp_authentication, 2),
2736 CreateMockRead(*body_authentication, 3),
2737 CreateMockRead(*resp_data, 5),
2738 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:062739 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:132740 };
2741
[email protected]dd54bd82012-07-19 23:44:572742 OrderedSocketData data(
2743 spdy_reads, arraysize(spdy_reads),
2744 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072745 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:132746
[email protected]8ddf8322012-02-23 18:08:062747 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022748 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072749 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:132750
[email protected]49639fa2011-12-20 23:22:412751 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132752
[email protected]262eec82013-03-19 21:01:362753 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502754 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:132755
[email protected]49639fa2011-12-20 23:22:412756 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:132757 EXPECT_EQ(ERR_IO_PENDING, rv);
2758
2759 rv = callback1.WaitForResult();
2760 EXPECT_EQ(OK, rv);
2761
2762 const HttpResponseInfo* const response = trans->GetResponseInfo();
2763
2764 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502765 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132766 EXPECT_EQ(407, response->headers->response_code());
2767 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042768 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132769
[email protected]49639fa2011-12-20 23:22:412770 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132771
[email protected]49639fa2011-12-20 23:22:412772 rv = trans->RestartWithAuth(
2773 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:132774 EXPECT_EQ(ERR_IO_PENDING, rv);
2775
2776 rv = callback2.WaitForResult();
2777 EXPECT_EQ(OK, rv);
2778
2779 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2780
2781 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:502782 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132783 EXPECT_EQ(200, response_restart->headers->response_code());
2784 // The password prompt info should not be set.
2785 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2786}
2787
[email protected]d9da5fe2010-10-13 22:37:162788// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:022789TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272790 HttpRequestInfo request;
2791 request.method = "GET";
2792 request.url = GURL("https://www.google.com/");
2793 request.load_flags = 0;
2794
[email protected]d9da5fe2010-10-13 22:37:162795 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072796 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112797 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292798 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072799 session_deps_.net_log = log.bound().net_log();
2800 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162801
[email protected]262eec82013-03-19 21:01:362802 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502803 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162804
[email protected]d9da5fe2010-10-13 22:37:162805 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542806 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2807 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162808 // fetch https://www.google.com/ via HTTP
2809
2810 const char get[] = "GET / HTTP/1.1\r\n"
2811 "Host: www.google.com\r\n"
2812 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192813 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:022814 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2815 scoped_ptr<SpdyFrame> conn_resp(
2816 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162817 const char resp[] = "HTTP/1.1 200 OK\r\n"
2818 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192819 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022820 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:192821 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:022822 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:192823 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:202824 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:042825
2826 MockWrite spdy_writes[] = {
2827 CreateMockWrite(*connect, 1),
2828 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:462829 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:042830 };
2831
[email protected]d9da5fe2010-10-13 22:37:162832 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062833 CreateMockRead(*conn_resp, 2, ASYNC),
2834 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2835 CreateMockRead(*wrapped_body, 6, ASYNC),
2836 CreateMockRead(*wrapped_body, 7, ASYNC),
2837 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162838 };
2839
[email protected]dd54bd82012-07-19 23:44:572840 OrderedSocketData spdy_data(
2841 spdy_reads, arraysize(spdy_reads),
2842 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072843 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162844
[email protected]8ddf8322012-02-23 18:08:062845 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022846 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072847 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062848 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:162849 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:462850 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:072851 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162852
[email protected]49639fa2011-12-20 23:22:412853 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162854
[email protected]49639fa2011-12-20 23:22:412855 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162856 EXPECT_EQ(ERR_IO_PENDING, rv);
2857
2858 rv = callback1.WaitForResult();
2859 EXPECT_EQ(OK, rv);
2860
[email protected]58e32bb2013-01-21 18:23:252861 LoadTimingInfo load_timing_info;
2862 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2863 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2864
[email protected]d9da5fe2010-10-13 22:37:162865 const HttpResponseInfo* response = trans->GetResponseInfo();
2866 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502867 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162868 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2869
2870 std::string response_data;
2871 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2872 EXPECT_EQ("1234567890", response_data);
2873}
2874
2875// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:022876TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:272877 HttpRequestInfo request;
2878 request.method = "GET";
2879 request.url = GURL("https://www.google.com/");
2880 request.load_flags = 0;
2881
[email protected]d9da5fe2010-10-13 22:37:162882 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072883 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112884 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292885 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072886 session_deps_.net_log = log.bound().net_log();
2887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162888
[email protected]262eec82013-03-19 21:01:362889 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162891
[email protected]d9da5fe2010-10-13 22:37:162892 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542893 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2894 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162895 // fetch https://www.google.com/ via SPDY
2896 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:462897 scoped_ptr<SpdyFrame> get(
2898 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:022899 scoped_ptr<SpdyFrame> wrapped_get(
2900 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
2901 scoped_ptr<SpdyFrame> conn_resp(
2902 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2903 scoped_ptr<SpdyFrame> get_resp(
2904 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:192905 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022906 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
2907 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2908 scoped_ptr<SpdyFrame> wrapped_body(
2909 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:192910 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:202911 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:192912 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:202913 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:042914
2915 MockWrite spdy_writes[] = {
2916 CreateMockWrite(*connect, 1),
2917 CreateMockWrite(*wrapped_get, 3),
2918 CreateMockWrite(*window_update_get_resp, 5),
2919 CreateMockWrite(*window_update_body, 7),
2920 };
2921
[email protected]d9da5fe2010-10-13 22:37:162922 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062923 CreateMockRead(*conn_resp, 2, ASYNC),
2924 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2925 CreateMockRead(*wrapped_body, 6, ASYNC),
2926 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162927 };
2928
[email protected]dd54bd82012-07-19 23:44:572929 OrderedSocketData spdy_data(
2930 spdy_reads, arraysize(spdy_reads),
2931 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072932 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162933
[email protected]8ddf8322012-02-23 18:08:062934 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022935 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072936 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062937 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022938 ssl2.SetNextProto(GetParam());
2939 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:072940 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162941
[email protected]49639fa2011-12-20 23:22:412942 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162943
[email protected]49639fa2011-12-20 23:22:412944 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162945 EXPECT_EQ(ERR_IO_PENDING, rv);
2946
2947 rv = callback1.WaitForResult();
2948 EXPECT_EQ(OK, rv);
2949
[email protected]58e32bb2013-01-21 18:23:252950 LoadTimingInfo load_timing_info;
2951 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2952 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2953
[email protected]d9da5fe2010-10-13 22:37:162954 const HttpResponseInfo* response = trans->GetResponseInfo();
2955 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502956 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162957 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2958
2959 std::string response_data;
2960 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232961 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:162962}
2963
2964// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022965TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:272966 HttpRequestInfo request;
2967 request.method = "GET";
2968 request.url = GURL("https://www.google.com/");
2969 request.load_flags = 0;
2970
[email protected]d9da5fe2010-10-13 22:37:162971 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072972 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112973 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292974 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072975 session_deps_.net_log = log.bound().net_log();
2976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162977
[email protected]262eec82013-03-19 21:01:362978 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162980
[email protected]d9da5fe2010-10-13 22:37:162981 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542982 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2983 LOWEST));
[email protected]c10b20852013-05-15 21:29:202984 scoped_ptr<SpdyFrame> get(
2985 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:162986
2987 MockWrite spdy_writes[] = {
2988 CreateMockWrite(*connect, 1),
2989 CreateMockWrite(*get, 3),
2990 };
2991
[email protected]23e482282013-06-14 16:08:022992 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
2993 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:162994 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062995 CreateMockRead(*resp, 2, ASYNC),
2996 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:162997 };
2998
[email protected]dd54bd82012-07-19 23:44:572999 OrderedSocketData spdy_data(
3000 spdy_reads, arraysize(spdy_reads),
3001 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073002 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163003
[email protected]8ddf8322012-02-23 18:08:063004 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023005 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073006 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063007 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023008 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073009 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163010
[email protected]49639fa2011-12-20 23:22:413011 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163012
[email protected]49639fa2011-12-20 23:22:413013 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163014 EXPECT_EQ(ERR_IO_PENDING, rv);
3015
3016 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173017 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163018
[email protected]4eddbc732012-08-09 05:40:173019 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163020}
3021
[email protected]f6c63db52013-02-02 00:35:223022// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3023// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023024TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223025 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3026 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073027 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223028 "https://proxy:70"));
3029 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073030 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223031 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073032 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223033
3034 HttpRequestInfo request1;
3035 request1.method = "GET";
3036 request1.url = GURL("https://www.google.com/");
3037 request1.load_flags = 0;
3038
3039 HttpRequestInfo request2;
3040 request2.method = "GET";
3041 request2.url = GURL("https://news.google.com/");
3042 request2.load_flags = 0;
3043
3044 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543045 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3046 LOWEST));
[email protected]23e482282013-06-14 16:08:023047 scoped_ptr<SpdyFrame> conn_resp1(
3048 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223049
3050 // Fetch https://www.google.com/ via HTTP.
3051 const char get1[] = "GET / HTTP/1.1\r\n"
3052 "Host: www.google.com\r\n"
3053 "Connection: keep-alive\r\n\r\n";
3054 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023055 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223056 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3057 "Content-Length: 1\r\n\r\n";
3058 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023059 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3060 scoped_ptr<SpdyFrame> wrapped_body1(
3061 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223062 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203063 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223064
3065 // CONNECT to news.google.com:443 via SPDY.
3066 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023067 spdy_util_.GetMethodKey(), "CONNECT",
3068 spdy_util_.GetPathKey(), "news.google.com:443",
3069 spdy_util_.GetHostKey(), "news.google.com",
3070 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223071 };
3072 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233073 spdy_util_.ConstructSpdyControlFrame(NULL,
3074 0,
3075 /*compressed*/ false,
3076 3,
3077 LOWEST,
3078 SYN_STREAM,
3079 CONTROL_FLAG_NONE,
3080 kConnectHeaders2,
3081 arraysize(kConnectHeaders2),
3082 0));
[email protected]23e482282013-06-14 16:08:023083 scoped_ptr<SpdyFrame> conn_resp2(
3084 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223085
3086 // Fetch https://news.google.com/ via HTTP.
3087 const char get2[] = "GET / HTTP/1.1\r\n"
3088 "Host: news.google.com\r\n"
3089 "Connection: keep-alive\r\n\r\n";
3090 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023091 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223092 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3093 "Content-Length: 2\r\n\r\n";
3094 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023095 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223096 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023097 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223098
3099 MockWrite spdy_writes[] = {
3100 CreateMockWrite(*connect1, 0),
3101 CreateMockWrite(*wrapped_get1, 2),
3102 CreateMockWrite(*connect2, 5),
3103 CreateMockWrite(*wrapped_get2, 7),
3104 };
3105
3106 MockRead spdy_reads[] = {
3107 CreateMockRead(*conn_resp1, 1, ASYNC),
3108 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3109 CreateMockRead(*wrapped_body1, 4, ASYNC),
3110 CreateMockRead(*conn_resp2, 6, ASYNC),
3111 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3112 CreateMockRead(*wrapped_body2, 9, ASYNC),
3113 MockRead(ASYNC, 0, 10),
3114 };
3115
3116 DeterministicSocketData spdy_data(
3117 spdy_reads, arraysize(spdy_reads),
3118 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073119 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223120
3121 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023122 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073123 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223124 SSLSocketDataProvider ssl2(ASYNC, OK);
3125 ssl2.was_npn_negotiated = false;
3126 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073127 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223128 SSLSocketDataProvider ssl3(ASYNC, OK);
3129 ssl3.was_npn_negotiated = false;
3130 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073131 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223132
3133 TestCompletionCallback callback;
3134
[email protected]262eec82013-03-19 21:01:363135 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223137 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3138 EXPECT_EQ(ERR_IO_PENDING, rv);
3139 // The first connect and request, each of their responses, and the body.
3140 spdy_data.RunFor(5);
3141
3142 rv = callback.WaitForResult();
3143 EXPECT_EQ(OK, rv);
3144
3145 LoadTimingInfo load_timing_info;
3146 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3147 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3148
3149 const HttpResponseInfo* response = trans->GetResponseInfo();
3150 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503151 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223152 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3153
3154 std::string response_data;
3155 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503156 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223157
[email protected]262eec82013-03-19 21:01:363158 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503159 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223160 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3161 EXPECT_EQ(ERR_IO_PENDING, rv);
3162
3163 // The second connect and request, each of their responses, and the body.
3164 spdy_data.RunFor(5);
3165 rv = callback.WaitForResult();
3166 EXPECT_EQ(OK, rv);
3167
3168 LoadTimingInfo load_timing_info2;
3169 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3170 // Even though the SPDY connection is reused, a new tunnelled connection has
3171 // to be created, so the socket's load timing looks like a fresh connection.
3172 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3173
3174 // The requests should have different IDs, since they each are using their own
3175 // separate stream.
3176 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3177
[email protected]90499482013-06-01 00:39:503178 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223179}
3180
3181// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3182// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023183TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223184 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3185 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073186 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223187 "https://proxy:70"));
3188 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073189 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223190 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073191 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223192
3193 HttpRequestInfo request1;
3194 request1.method = "GET";
3195 request1.url = GURL("https://www.google.com/");
3196 request1.load_flags = 0;
3197
3198 HttpRequestInfo request2;
3199 request2.method = "GET";
3200 request2.url = GURL("https://www.google.com/2");
3201 request2.load_flags = 0;
3202
3203 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543204 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3205 LOWEST));
[email protected]23e482282013-06-14 16:08:023206 scoped_ptr<SpdyFrame> conn_resp1(
3207 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223208
3209 // Fetch https://www.google.com/ via HTTP.
3210 const char get1[] = "GET / HTTP/1.1\r\n"
3211 "Host: www.google.com\r\n"
3212 "Connection: keep-alive\r\n\r\n";
3213 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023214 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223215 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3216 "Content-Length: 1\r\n\r\n";
3217 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023218 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3219 scoped_ptr<SpdyFrame> wrapped_body1(
3220 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223221 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203222 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223223
3224 // Fetch https://www.google.com/2 via HTTP.
3225 const char get2[] = "GET /2 HTTP/1.1\r\n"
3226 "Host: www.google.com\r\n"
3227 "Connection: keep-alive\r\n\r\n";
3228 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023229 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223230 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3231 "Content-Length: 2\r\n\r\n";
3232 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023233 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223234 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023235 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223236
3237 MockWrite spdy_writes[] = {
3238 CreateMockWrite(*connect1, 0),
3239 CreateMockWrite(*wrapped_get1, 2),
3240 CreateMockWrite(*wrapped_get2, 5),
3241 };
3242
3243 MockRead spdy_reads[] = {
3244 CreateMockRead(*conn_resp1, 1, ASYNC),
3245 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3246 CreateMockRead(*wrapped_body1, 4, ASYNC),
3247 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3248 CreateMockRead(*wrapped_body2, 7, ASYNC),
3249 MockRead(ASYNC, 0, 8),
3250 };
3251
3252 DeterministicSocketData spdy_data(
3253 spdy_reads, arraysize(spdy_reads),
3254 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073255 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223256
3257 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023258 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073259 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223260 SSLSocketDataProvider ssl2(ASYNC, OK);
3261 ssl2.was_npn_negotiated = false;
3262 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073263 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223264
3265 TestCompletionCallback callback;
3266
[email protected]262eec82013-03-19 21:01:363267 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223269 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3270 EXPECT_EQ(ERR_IO_PENDING, rv);
3271 // The first connect and request, each of their responses, and the body.
3272 spdy_data.RunFor(5);
3273
3274 rv = callback.WaitForResult();
3275 EXPECT_EQ(OK, rv);
3276
3277 LoadTimingInfo load_timing_info;
3278 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3279 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3280
3281 const HttpResponseInfo* response = trans->GetResponseInfo();
3282 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503283 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223284 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3285
3286 std::string response_data;
3287 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503288 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223289 trans.reset();
3290
[email protected]262eec82013-03-19 21:01:363291 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503292 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223293 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3294 EXPECT_EQ(ERR_IO_PENDING, rv);
3295
3296 // The second request, response, and body. There should not be a second
3297 // connect.
3298 spdy_data.RunFor(3);
3299 rv = callback.WaitForResult();
3300 EXPECT_EQ(OK, rv);
3301
3302 LoadTimingInfo load_timing_info2;
3303 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3304 TestLoadTimingReused(load_timing_info2);
3305
3306 // The requests should have the same ID.
3307 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3308
[email protected]90499482013-06-01 00:39:503309 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223310}
3311
3312// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3313// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023314TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223315 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3316 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073317 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223318 "https://proxy:70"));
3319 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073320 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223321 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073322 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223323
3324 HttpRequestInfo request1;
3325 request1.method = "GET";
3326 request1.url = GURL("http://www.google.com/");
3327 request1.load_flags = 0;
3328
3329 HttpRequestInfo request2;
3330 request2.method = "GET";
3331 request2.url = GURL("http://news.google.com/");
3332 request2.load_flags = 0;
3333
3334 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023335 scoped_ptr<SpdyHeaderBlock> headers(
3336 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233337 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023338 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3339 scoped_ptr<SpdyFrame> get_resp1(
3340 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3341 scoped_ptr<SpdyFrame> body1(
3342 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223343
3344 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023345 scoped_ptr<SpdyHeaderBlock> headers2(
3346 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233347 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023348 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3349 scoped_ptr<SpdyFrame> get_resp2(
3350 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3351 scoped_ptr<SpdyFrame> body2(
3352 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223353
3354 MockWrite spdy_writes[] = {
3355 CreateMockWrite(*get1, 0),
3356 CreateMockWrite(*get2, 3),
3357 };
3358
3359 MockRead spdy_reads[] = {
3360 CreateMockRead(*get_resp1, 1, ASYNC),
3361 CreateMockRead(*body1, 2, ASYNC),
3362 CreateMockRead(*get_resp2, 4, ASYNC),
3363 CreateMockRead(*body2, 5, ASYNC),
3364 MockRead(ASYNC, 0, 6),
3365 };
3366
3367 DeterministicSocketData spdy_data(
3368 spdy_reads, arraysize(spdy_reads),
3369 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073370 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223371
3372 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023373 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073374 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223375
3376 TestCompletionCallback callback;
3377
[email protected]262eec82013-03-19 21:01:363378 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503379 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223380 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3381 EXPECT_EQ(ERR_IO_PENDING, rv);
3382 spdy_data.RunFor(2);
3383
3384 rv = callback.WaitForResult();
3385 EXPECT_EQ(OK, rv);
3386
3387 LoadTimingInfo load_timing_info;
3388 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3389 TestLoadTimingNotReused(load_timing_info,
3390 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3391
3392 const HttpResponseInfo* response = trans->GetResponseInfo();
3393 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503394 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223395 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3396
3397 std::string response_data;
3398 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503399 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223400 spdy_data.RunFor(1);
3401 EXPECT_EQ(1, callback.WaitForResult());
3402 // Delete the first request, so the second one can reuse the socket.
3403 trans.reset();
3404
[email protected]262eec82013-03-19 21:01:363405 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503406 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223407 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3408 EXPECT_EQ(ERR_IO_PENDING, rv);
3409
3410 spdy_data.RunFor(2);
3411 rv = callback.WaitForResult();
3412 EXPECT_EQ(OK, rv);
3413
3414 LoadTimingInfo load_timing_info2;
3415 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3416 TestLoadTimingReused(load_timing_info2);
3417
3418 // The requests should have the same ID.
3419 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3420
[email protected]90499482013-06-01 00:39:503421 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223422 spdy_data.RunFor(1);
3423 EXPECT_EQ(2, callback.WaitForResult());
3424}
3425
[email protected]2df19bb2010-08-25 20:13:463426// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023427TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463428 HttpRequestInfo request;
3429 request.method = "GET";
3430 request.url = GURL("http://www.google.com/");
3431 // when the no authentication data flag is set.
3432 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3433
[email protected]79cb5c12011-09-12 13:12:043434 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073435 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043436 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293437 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073438 session_deps_.net_log = log.bound().net_log();
3439 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273440
[email protected]2df19bb2010-08-25 20:13:463441 // Since we have proxy, should use full url
3442 MockWrite data_writes1[] = {
3443 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3444 "Host: www.google.com\r\n"
3445 "Proxy-Connection: keep-alive\r\n\r\n"),
3446
3447 // After calling trans->RestartWithAuth(), this is the request we should
3448 // be issuing -- the final header line contains the credentials.
3449 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3450 "Host: www.google.com\r\n"
3451 "Proxy-Connection: keep-alive\r\n"
3452 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3453 };
3454
3455 // The proxy responds to the GET with a 407, using a persistent
3456 // connection.
3457 MockRead data_reads1[] = {
3458 // No credentials.
3459 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3460 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3461 MockRead("Proxy-Connection: keep-alive\r\n"),
3462 MockRead("Content-Length: 0\r\n\r\n"),
3463
3464 MockRead("HTTP/1.1 200 OK\r\n"),
3465 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3466 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063467 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463468 };
3469
3470 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3471 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073472 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063473 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073474 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463475
[email protected]49639fa2011-12-20 23:22:413476 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463477
[email protected]262eec82013-03-19 21:01:363478 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503479 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503480
[email protected]49639fa2011-12-20 23:22:413481 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463482 EXPECT_EQ(ERR_IO_PENDING, rv);
3483
3484 rv = callback1.WaitForResult();
3485 EXPECT_EQ(OK, rv);
3486
[email protected]58e32bb2013-01-21 18:23:253487 LoadTimingInfo load_timing_info;
3488 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3489 TestLoadTimingNotReused(load_timing_info,
3490 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3491
[email protected]2df19bb2010-08-25 20:13:463492 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503493 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503494 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463495 EXPECT_EQ(407, response->headers->response_code());
3496 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043497 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463498
[email protected]49639fa2011-12-20 23:22:413499 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463500
[email protected]49639fa2011-12-20 23:22:413501 rv = trans->RestartWithAuth(
3502 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463503 EXPECT_EQ(ERR_IO_PENDING, rv);
3504
3505 rv = callback2.WaitForResult();
3506 EXPECT_EQ(OK, rv);
3507
[email protected]58e32bb2013-01-21 18:23:253508 load_timing_info = LoadTimingInfo();
3509 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3510 // Retrying with HTTP AUTH is considered to be reusing a socket.
3511 TestLoadTimingReused(load_timing_info);
3512
[email protected]2df19bb2010-08-25 20:13:463513 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503514 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463515
3516 EXPECT_TRUE(response->headers->IsKeepAlive());
3517 EXPECT_EQ(200, response->headers->response_code());
3518 EXPECT_EQ(100, response->headers->GetContentLength());
3519 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3520
3521 // The password prompt info should not be set.
3522 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3523}
3524
[email protected]23e482282013-06-14 16:08:023525void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083526 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423527 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083528 request.method = "GET";
3529 request.url = GURL("https://www.google.com/");
3530 request.load_flags = 0;
3531
[email protected]cb9bf6ca2011-01-28 13:15:273532 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073533 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073534 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273535
[email protected]c744cf22009-02-27 07:28:083536 // Since we have proxy, should try to establish tunnel.
3537 MockWrite data_writes[] = {
3538 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453539 "Host: www.google.com\r\n"
3540 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083541 };
3542
3543 MockRead data_reads[] = {
3544 status,
3545 MockRead("Content-Length: 10\r\n\r\n"),
3546 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063547 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083548 };
3549
[email protected]31a2bfe2010-02-09 08:03:393550 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3551 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073552 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083553
[email protected]49639fa2011-12-20 23:22:413554 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083555
[email protected]262eec82013-03-19 21:01:363556 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503558
[email protected]49639fa2011-12-20 23:22:413559 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423560 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083561
3562 rv = callback.WaitForResult();
3563 EXPECT_EQ(expected_status, rv);
3564}
3565
[email protected]23e482282013-06-14 16:08:023566void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233567 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083568 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423569 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083570}
3571
[email protected]23e482282013-06-14 16:08:023572TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083573 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3574}
3575
[email protected]23e482282013-06-14 16:08:023576TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083577 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3578}
3579
[email protected]23e482282013-06-14 16:08:023580TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083581 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3582}
3583
[email protected]23e482282013-06-14 16:08:023584TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083585 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3586}
3587
[email protected]23e482282013-06-14 16:08:023588TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083589 ConnectStatusHelper(
3590 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3591}
3592
[email protected]23e482282013-06-14 16:08:023593TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083594 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3595}
3596
[email protected]23e482282013-06-14 16:08:023597TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083598 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3599}
3600
[email protected]23e482282013-06-14 16:08:023601TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083602 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3603}
3604
[email protected]23e482282013-06-14 16:08:023605TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083606 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3607}
3608
[email protected]23e482282013-06-14 16:08:023609TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083610 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3611}
3612
[email protected]23e482282013-06-14 16:08:023613TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083614 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3615}
3616
[email protected]23e482282013-06-14 16:08:023617TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083618 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3619}
3620
[email protected]23e482282013-06-14 16:08:023621TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083622 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3623}
3624
[email protected]23e482282013-06-14 16:08:023625TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083626 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3627}
3628
[email protected]23e482282013-06-14 16:08:023629TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083630 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3631}
3632
[email protected]23e482282013-06-14 16:08:023633TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083634 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3635}
3636
[email protected]23e482282013-06-14 16:08:023637TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083638 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3639}
3640
[email protected]23e482282013-06-14 16:08:023641TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083642 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3643}
3644
[email protected]23e482282013-06-14 16:08:023645TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083646 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3647}
3648
[email protected]23e482282013-06-14 16:08:023649TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083650 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3651}
3652
[email protected]23e482282013-06-14 16:08:023653TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083654 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3655}
3656
[email protected]23e482282013-06-14 16:08:023657TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083658 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3659}
3660
[email protected]23e482282013-06-14 16:08:023661TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083662 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3663}
3664
[email protected]23e482282013-06-14 16:08:023665TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083666 ConnectStatusHelperWithExpectedStatus(
3667 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543668 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083669}
3670
[email protected]23e482282013-06-14 16:08:023671TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083672 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3673}
3674
[email protected]23e482282013-06-14 16:08:023675TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083676 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3677}
3678
[email protected]23e482282013-06-14 16:08:023679TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083680 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3681}
3682
[email protected]23e482282013-06-14 16:08:023683TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083684 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3685}
3686
[email protected]23e482282013-06-14 16:08:023687TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083688 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3689}
3690
[email protected]23e482282013-06-14 16:08:023691TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083692 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3693}
3694
[email protected]23e482282013-06-14 16:08:023695TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083696 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3697}
3698
[email protected]23e482282013-06-14 16:08:023699TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083700 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3701}
3702
[email protected]23e482282013-06-14 16:08:023703TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083704 ConnectStatusHelper(
3705 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3706}
3707
[email protected]23e482282013-06-14 16:08:023708TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083709 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3710}
3711
[email protected]23e482282013-06-14 16:08:023712TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083713 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3714}
3715
[email protected]23e482282013-06-14 16:08:023716TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083717 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3718}
3719
[email protected]23e482282013-06-14 16:08:023720TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083721 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3722}
3723
[email protected]23e482282013-06-14 16:08:023724TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083725 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3726}
3727
[email protected]23e482282013-06-14 16:08:023728TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083729 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3730}
3731
[email protected]23e482282013-06-14 16:08:023732TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083733 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3734}
3735
[email protected]038e9a32008-10-08 22:40:163736// Test the flow when both the proxy server AND origin server require
3737// authentication. Again, this uses basic auth for both since that is
3738// the simplest to mock.
[email protected]23e482282013-06-14 16:08:023739TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:273740 HttpRequestInfo request;
3741 request.method = "GET";
3742 request.url = GURL("http://www.google.com/");
3743 request.load_flags = 0;
3744
[email protected]038e9a32008-10-08 22:40:163745 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:073746 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3747 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3748
3749 scoped_ptr<HttpTransaction> trans(
3750 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:163751
[email protected]f9ee6b52008-11-08 06:46:233752 MockWrite data_writes1[] = {
3753 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3754 "Host: www.google.com\r\n"
3755 "Proxy-Connection: keep-alive\r\n\r\n"),
3756 };
3757
[email protected]038e9a32008-10-08 22:40:163758 MockRead data_reads1[] = {
3759 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3760 // Give a couple authenticate options (only the middle one is actually
3761 // supported).
[email protected]22927ad2009-09-21 19:56:193762 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:163763 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3764 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3765 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3766 // Large content-length -- won't matter, as connection will be reset.
3767 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063768 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:163769 };
3770
3771 // After calling trans->RestartWithAuth() the first time, this is the
3772 // request we should be issuing -- the final header line contains the
3773 // proxy's credentials.
3774 MockWrite data_writes2[] = {
3775 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3776 "Host: www.google.com\r\n"
3777 "Proxy-Connection: keep-alive\r\n"
3778 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3779 };
3780
3781 // Now the proxy server lets the request pass through to origin server.
3782 // The origin server responds with a 401.
3783 MockRead data_reads2[] = {
3784 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3785 // Note: We are using the same realm-name as the proxy server. This is
3786 // completely valid, as realms are unique across hosts.
3787 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3788 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3789 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063790 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:163791 };
3792
3793 // After calling trans->RestartWithAuth() the second time, we should send
3794 // the credentials for both the proxy and origin server.
3795 MockWrite data_writes3[] = {
3796 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3797 "Host: www.google.com\r\n"
3798 "Proxy-Connection: keep-alive\r\n"
3799 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3800 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3801 };
3802
3803 // Lastly we get the desired content.
3804 MockRead data_reads3[] = {
3805 MockRead("HTTP/1.0 200 OK\r\n"),
3806 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3807 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063808 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:163809 };
3810
[email protected]31a2bfe2010-02-09 08:03:393811 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3812 data_writes1, arraysize(data_writes1));
3813 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3814 data_writes2, arraysize(data_writes2));
3815 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3816 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:073817 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3818 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3819 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:163820
[email protected]49639fa2011-12-20 23:22:413821 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:163822
[email protected]49639fa2011-12-20 23:22:413823 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423824 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163825
3826 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423827 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163828
[email protected]1c773ea12009-04-28 19:58:423829 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503830 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043831 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163832
[email protected]49639fa2011-12-20 23:22:413833 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:163834
[email protected]49639fa2011-12-20 23:22:413835 rv = trans->RestartWithAuth(
3836 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423837 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163838
3839 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423840 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163841
3842 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503843 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043844 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163845
[email protected]49639fa2011-12-20 23:22:413846 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:163847
[email protected]49639fa2011-12-20 23:22:413848 rv = trans->RestartWithAuth(
3849 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423850 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163851
3852 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423853 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163854
3855 response = trans->GetResponseInfo();
3856 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3857 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:163858}
[email protected]4ddaf2502008-10-23 18:26:193859
[email protected]ea9dc9a2009-09-05 00:43:323860// For the NTLM implementation using SSPI, we skip the NTLM tests since we
3861// can't hook into its internals to cause it to generate predictable NTLM
3862// authorization headers.
3863#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:293864// The NTLM authentication unit tests were generated by capturing the HTTP
3865// requests and responses using Fiddler 2 and inspecting the generated random
3866// bytes in the debugger.
3867
3868// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:023869TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:423870 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:243871 request.method = "GET";
3872 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:543873
3874 // Ensure load is not disrupted by flags which suppress behaviour specific
3875 // to other auth schemes.
3876 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:243877
[email protected]cb9bf6ca2011-01-28 13:15:273878 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
3879 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:073880 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273881
[email protected]3f918782009-02-28 01:29:243882 MockWrite data_writes1[] = {
3883 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3884 "Host: 172.22.68.17\r\n"
3885 "Connection: keep-alive\r\n\r\n"),
3886 };
3887
3888 MockRead data_reads1[] = {
3889 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043890 // Negotiate and NTLM are often requested together. However, we only want
3891 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3892 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:243893 MockRead("WWW-Authenticate: NTLM\r\n"),
3894 MockRead("Connection: close\r\n"),
3895 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363896 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243897 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:063898 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:243899 };
3900
3901 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:223902 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:243903 // request we should be issuing -- the final header line contains a Type
3904 // 1 message.
3905 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3906 "Host: 172.22.68.17\r\n"
3907 "Connection: keep-alive\r\n"
3908 "Authorization: NTLM "
3909 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3910
3911 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3912 // (the credentials for the origin server). The second request continues
3913 // on the same connection.
3914 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3915 "Host: 172.22.68.17\r\n"
3916 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:293917 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3918 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3919 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
3920 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
3921 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243922 };
3923
3924 MockRead data_reads2[] = {
3925 // The origin server responds with a Type 2 message.
3926 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3927 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:293928 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:243929 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3930 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3931 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3932 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3933 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3934 "BtAAAAAAA=\r\n"),
3935 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363936 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243937 MockRead("You are not authorized to view this page\r\n"),
3938
3939 // Lastly we get the desired content.
3940 MockRead("HTTP/1.1 200 OK\r\n"),
3941 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3942 MockRead("Content-Length: 13\r\n\r\n"),
3943 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:063944 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:243945 };
3946
[email protected]31a2bfe2010-02-09 08:03:393947 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3948 data_writes1, arraysize(data_writes1));
3949 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3950 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073951 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3952 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:243953
[email protected]49639fa2011-12-20 23:22:413954 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:243955
[email protected]262eec82013-03-19 21:01:363956 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503958
[email protected]49639fa2011-12-20 23:22:413959 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423960 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243961
3962 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423963 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243964
[email protected]0757e7702009-03-27 04:00:223965 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3966
[email protected]1c773ea12009-04-28 19:58:423967 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043968 ASSERT_FALSE(response == NULL);
3969 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:243970
[email protected]49639fa2011-12-20 23:22:413971 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:253972
[email protected]f3cf9802011-10-28 18:44:583973 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:413974 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:253975 EXPECT_EQ(ERR_IO_PENDING, rv);
3976
3977 rv = callback2.WaitForResult();
3978 EXPECT_EQ(OK, rv);
3979
3980 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3981
3982 response = trans->GetResponseInfo();
3983 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:253984 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3985
[email protected]49639fa2011-12-20 23:22:413986 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:243987
[email protected]49639fa2011-12-20 23:22:413988 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423989 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243990
[email protected]0757e7702009-03-27 04:00:223991 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423992 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243993
3994 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503995 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:243996 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3997 EXPECT_EQ(13, response->headers->GetContentLength());
3998}
3999
[email protected]385a4672009-03-11 22:21:294000// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024001TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424002 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294003 request.method = "GET";
4004 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4005 request.load_flags = 0;
4006
[email protected]cb9bf6ca2011-01-28 13:15:274007 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4008 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074009 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274010
[email protected]385a4672009-03-11 22:21:294011 MockWrite data_writes1[] = {
4012 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4013 "Host: 172.22.68.17\r\n"
4014 "Connection: keep-alive\r\n\r\n"),
4015 };
4016
4017 MockRead data_reads1[] = {
4018 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044019 // Negotiate and NTLM are often requested together. However, we only want
4020 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4021 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294022 MockRead("WWW-Authenticate: NTLM\r\n"),
4023 MockRead("Connection: close\r\n"),
4024 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364025 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294026 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064027 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294028 };
4029
4030 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224031 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294032 // request we should be issuing -- the final header line contains a Type
4033 // 1 message.
4034 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4035 "Host: 172.22.68.17\r\n"
4036 "Connection: keep-alive\r\n"
4037 "Authorization: NTLM "
4038 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4039
4040 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4041 // (the credentials for the origin server). The second request continues
4042 // on the same connection.
4043 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4044 "Host: 172.22.68.17\r\n"
4045 "Connection: keep-alive\r\n"
4046 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4047 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4048 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4049 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4050 "4Ww7b7E=\r\n\r\n"),
4051 };
4052
4053 MockRead data_reads2[] = {
4054 // The origin server responds with a Type 2 message.
4055 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4056 MockRead("WWW-Authenticate: NTLM "
4057 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4058 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4059 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4060 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4061 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4062 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4063 "BtAAAAAAA=\r\n"),
4064 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364065 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294066 MockRead("You are not authorized to view this page\r\n"),
4067
4068 // Wrong password.
4069 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294070 MockRead("WWW-Authenticate: NTLM\r\n"),
4071 MockRead("Connection: close\r\n"),
4072 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364073 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294074 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064075 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294076 };
4077
4078 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224079 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294080 // request we should be issuing -- the final header line contains a Type
4081 // 1 message.
4082 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4083 "Host: 172.22.68.17\r\n"
4084 "Connection: keep-alive\r\n"
4085 "Authorization: NTLM "
4086 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4087
4088 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4089 // (the credentials for the origin server). The second request continues
4090 // on the same connection.
4091 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4092 "Host: 172.22.68.17\r\n"
4093 "Connection: keep-alive\r\n"
4094 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4095 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4096 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4097 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4098 "+4MUm7c=\r\n\r\n"),
4099 };
4100
4101 MockRead data_reads3[] = {
4102 // The origin server responds with a Type 2 message.
4103 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4104 MockRead("WWW-Authenticate: NTLM "
4105 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4106 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4107 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4108 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4109 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4110 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4111 "BtAAAAAAA=\r\n"),
4112 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364113 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294114 MockRead("You are not authorized to view this page\r\n"),
4115
4116 // Lastly we get the desired content.
4117 MockRead("HTTP/1.1 200 OK\r\n"),
4118 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4119 MockRead("Content-Length: 13\r\n\r\n"),
4120 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064121 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294122 };
4123
[email protected]31a2bfe2010-02-09 08:03:394124 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4125 data_writes1, arraysize(data_writes1));
4126 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4127 data_writes2, arraysize(data_writes2));
4128 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4129 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074130 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4131 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4132 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294133
[email protected]49639fa2011-12-20 23:22:414134 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294135
[email protected]262eec82013-03-19 21:01:364136 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504138
[email protected]49639fa2011-12-20 23:22:414139 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424140 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294141
4142 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424143 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294144
[email protected]0757e7702009-03-27 04:00:224145 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294146
[email protected]1c773ea12009-04-28 19:58:424147 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504148 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044149 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294150
[email protected]49639fa2011-12-20 23:22:414151 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294152
[email protected]0757e7702009-03-27 04:00:224153 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584154 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414155 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424156 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294157
[email protected]10af5fe72011-01-31 16:17:254158 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424159 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294160
[email protected]0757e7702009-03-27 04:00:224161 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414162 TestCompletionCallback callback3;
4163 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424164 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254165 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424166 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224167 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4168
4169 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044170 ASSERT_FALSE(response == NULL);
4171 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224172
[email protected]49639fa2011-12-20 23:22:414173 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224174
4175 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584176 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414177 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254178 EXPECT_EQ(ERR_IO_PENDING, rv);
4179
4180 rv = callback4.WaitForResult();
4181 EXPECT_EQ(OK, rv);
4182
4183 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4184
[email protected]49639fa2011-12-20 23:22:414185 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254186
4187 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414188 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424189 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224190
4191 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424192 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224193
[email protected]385a4672009-03-11 22:21:294194 response = trans->GetResponseInfo();
4195 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4196 EXPECT_EQ(13, response->headers->GetContentLength());
4197}
[email protected]ea9dc9a2009-09-05 00:43:324198#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294199
[email protected]4ddaf2502008-10-23 18:26:194200// Test reading a server response which has only headers, and no body.
4201// After some maximum number of bytes is consumed, the transaction should
4202// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024203TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424204 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194205 request.method = "GET";
4206 request.url = GURL("http://www.google.com/");
4207 request.load_flags = 0;
4208
[email protected]3fe8d2f82013-10-17 08:56:074209 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274210 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274212
[email protected]b75b7b2f2009-10-06 00:54:534213 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434214 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534215 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194216
4217 MockRead data_reads[] = {
4218 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064219 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194220 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064221 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194222 };
[email protected]31a2bfe2010-02-09 08:03:394223 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074224 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194225
[email protected]49639fa2011-12-20 23:22:414226 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194227
[email protected]49639fa2011-12-20 23:22:414228 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424229 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194230
4231 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424232 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194233
[email protected]1c773ea12009-04-28 19:58:424234 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194235 EXPECT_TRUE(response == NULL);
4236}
[email protected]f4e426b2008-11-05 00:24:494237
4238// Make sure that we don't try to reuse a TCPClientSocket when failing to
4239// establish tunnel.
4240// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024241TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234242 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274243 HttpRequestInfo request;
4244 request.method = "GET";
4245 request.url = GURL("https://www.google.com/");
4246 request.load_flags = 0;
4247
[email protected]f4e426b2008-11-05 00:24:494248 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074249 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014250
[email protected]bb88e1d32013-05-03 23:11:074251 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494252
[email protected]262eec82013-03-19 21:01:364253 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504254 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494255
[email protected]f4e426b2008-11-05 00:24:494256 // Since we have proxy, should try to establish tunnel.
4257 MockWrite data_writes1[] = {
4258 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454259 "Host: www.google.com\r\n"
4260 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494261 };
4262
[email protected]77848d12008-11-14 00:00:224263 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494264 // connection. Usually a proxy would return 501 (not implemented),
4265 // or 200 (tunnel established).
4266 MockRead data_reads1[] = {
4267 MockRead("HTTP/1.1 404 Not Found\r\n"),
4268 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064269 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494270 };
4271
[email protected]31a2bfe2010-02-09 08:03:394272 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4273 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074274 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494275
[email protected]49639fa2011-12-20 23:22:414276 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494277
[email protected]49639fa2011-12-20 23:22:414278 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424279 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494280
4281 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424282 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494283
[email protected]1c773ea12009-04-28 19:58:424284 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084285 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494286
[email protected]b4404c02009-04-10 16:38:524287 // Empty the current queue. This is necessary because idle sockets are
4288 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344289 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524290
[email protected]f4e426b2008-11-05 00:24:494291 // We now check to make sure the TCPClientSocket was not added back to
4292 // the pool.
[email protected]90499482013-06-01 00:39:504293 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494294 trans.reset();
[email protected]2da659e2013-05-23 20:51:344295 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494296 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504297 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494298}
[email protected]372d34a2008-11-05 21:30:514299
[email protected]1b157c02009-04-21 01:55:404300// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024301TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424302 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404303 request.method = "GET";
4304 request.url = GURL("http://www.google.com/");
4305 request.load_flags = 0;
4306
[email protected]bb88e1d32013-05-03 23:11:074307 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274308
[email protected]262eec82013-03-19 21:01:364309 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504310 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274311
[email protected]1b157c02009-04-21 01:55:404312 MockRead data_reads[] = {
4313 // A part of the response body is received with the response headers.
4314 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4315 // The rest of the response body is received in two parts.
4316 MockRead("lo"),
4317 MockRead(" world"),
4318 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064319 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404320 };
4321
[email protected]31a2bfe2010-02-09 08:03:394322 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074323 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404324
[email protected]49639fa2011-12-20 23:22:414325 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404326
[email protected]49639fa2011-12-20 23:22:414327 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424328 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404329
4330 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424331 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404332
[email protected]1c773ea12009-04-28 19:58:424333 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504334 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404335
[email protected]90499482013-06-01 00:39:504336 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404337 std::string status_line = response->headers->GetStatusLine();
4338 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4339
[email protected]90499482013-06-01 00:39:504340 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404341
4342 std::string response_data;
4343 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424344 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404345 EXPECT_EQ("hello world", response_data);
4346
4347 // Empty the current queue. This is necessary because idle sockets are
4348 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344349 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404350
4351 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504352 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404353}
4354
[email protected]76a505b2010-08-25 06:23:004355// Make sure that we recycle a SSL socket after reading all of the response
4356// body.
[email protected]23e482282013-06-14 16:08:024357TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004358 HttpRequestInfo request;
4359 request.method = "GET";
4360 request.url = GURL("https://www.google.com/");
4361 request.load_flags = 0;
4362
4363 MockWrite data_writes[] = {
4364 MockWrite("GET / HTTP/1.1\r\n"
4365 "Host: www.google.com\r\n"
4366 "Connection: keep-alive\r\n\r\n"),
4367 };
4368
4369 MockRead data_reads[] = {
4370 MockRead("HTTP/1.1 200 OK\r\n"),
4371 MockRead("Content-Length: 11\r\n\r\n"),
4372 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064373 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004374 };
4375
[email protected]8ddf8322012-02-23 18:08:064376 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074377 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004378
4379 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4380 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074381 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004382
[email protected]49639fa2011-12-20 23:22:414383 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004384
[email protected]bb88e1d32013-05-03 23:11:074385 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364386 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504387 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004388
[email protected]49639fa2011-12-20 23:22:414389 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004390
4391 EXPECT_EQ(ERR_IO_PENDING, rv);
4392 EXPECT_EQ(OK, callback.WaitForResult());
4393
4394 const HttpResponseInfo* response = trans->GetResponseInfo();
4395 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504396 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004397 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4398
[email protected]90499482013-06-01 00:39:504399 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004400
4401 std::string response_data;
4402 rv = ReadTransaction(trans.get(), &response_data);
4403 EXPECT_EQ(OK, rv);
4404 EXPECT_EQ("hello world", response_data);
4405
4406 // Empty the current queue. This is necessary because idle sockets are
4407 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344408 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004409
4410 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504411 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004412}
4413
4414// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4415// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024416TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004417 HttpRequestInfo request;
4418 request.method = "GET";
4419 request.url = GURL("https://www.google.com/");
4420 request.load_flags = 0;
4421
4422 MockWrite data_writes[] = {
4423 MockWrite("GET / HTTP/1.1\r\n"
4424 "Host: www.google.com\r\n"
4425 "Connection: keep-alive\r\n\r\n"),
4426 MockWrite("GET / HTTP/1.1\r\n"
4427 "Host: www.google.com\r\n"
4428 "Connection: keep-alive\r\n\r\n"),
4429 };
4430
4431 MockRead data_reads[] = {
4432 MockRead("HTTP/1.1 200 OK\r\n"),
4433 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064434 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004435 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064436 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004437 };
4438
[email protected]8ddf8322012-02-23 18:08:064439 SSLSocketDataProvider ssl(ASYNC, OK);
4440 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074441 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4442 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004443
4444 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4445 data_writes, arraysize(data_writes));
4446 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4447 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074448 session_deps_.socket_factory->AddSocketDataProvider(&data);
4449 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004450
[email protected]49639fa2011-12-20 23:22:414451 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004452
[email protected]bb88e1d32013-05-03 23:11:074453 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364454 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004456
[email protected]49639fa2011-12-20 23:22:414457 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004458
4459 EXPECT_EQ(ERR_IO_PENDING, rv);
4460 EXPECT_EQ(OK, callback.WaitForResult());
4461
4462 const HttpResponseInfo* response = trans->GetResponseInfo();
4463 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504464 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004465 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4466
[email protected]90499482013-06-01 00:39:504467 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004468
4469 std::string response_data;
4470 rv = ReadTransaction(trans.get(), &response_data);
4471 EXPECT_EQ(OK, rv);
4472 EXPECT_EQ("hello world", response_data);
4473
4474 // Empty the current queue. This is necessary because idle sockets are
4475 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344476 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004477
4478 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504479 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004480
4481 // Now start the second transaction, which should reuse the previous socket.
4482
[email protected]90499482013-06-01 00:39:504483 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004484
[email protected]49639fa2011-12-20 23:22:414485 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004486
4487 EXPECT_EQ(ERR_IO_PENDING, rv);
4488 EXPECT_EQ(OK, callback.WaitForResult());
4489
4490 response = trans->GetResponseInfo();
4491 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504492 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004493 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4494
[email protected]90499482013-06-01 00:39:504495 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004496
4497 rv = ReadTransaction(trans.get(), &response_data);
4498 EXPECT_EQ(OK, rv);
4499 EXPECT_EQ("hello world", response_data);
4500
4501 // Empty the current queue. This is necessary because idle sockets are
4502 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344503 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004504
4505 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504506 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004507}
4508
[email protected]b4404c02009-04-10 16:38:524509// Make sure that we recycle a socket after a zero-length response.
4510// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024511TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424512 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524513 request.method = "GET";
4514 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4515 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4516 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4517 "rt=prt.2642,ol.2649,xjs.2951");
4518 request.load_flags = 0;
4519
[email protected]bb88e1d32013-05-03 23:11:074520 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274521
[email protected]262eec82013-03-19 21:01:364522 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504523 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274524
[email protected]b4404c02009-04-10 16:38:524525 MockRead data_reads[] = {
4526 MockRead("HTTP/1.1 204 No Content\r\n"
4527 "Content-Length: 0\r\n"
4528 "Content-Type: text/html\r\n\r\n"),
4529 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064530 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524531 };
4532
[email protected]31a2bfe2010-02-09 08:03:394533 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074534 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524535
[email protected]49639fa2011-12-20 23:22:414536 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524537
[email protected]49639fa2011-12-20 23:22:414538 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424539 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524540
4541 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424542 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524543
[email protected]1c773ea12009-04-28 19:58:424544 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504545 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524546
[email protected]90499482013-06-01 00:39:504547 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524548 std::string status_line = response->headers->GetStatusLine();
4549 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4550
[email protected]90499482013-06-01 00:39:504551 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524552
4553 std::string response_data;
4554 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424555 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524556 EXPECT_EQ("", response_data);
4557
4558 // Empty the current queue. This is necessary because idle sockets are
4559 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344560 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524561
4562 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504563 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524564}
4565
[email protected]23e482282013-06-14 16:08:024566TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064567 ScopedVector<UploadElementReader> element_readers;
4568 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204569 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274570
[email protected]1c773ea12009-04-28 19:58:424571 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514572 // Transaction 1: a GET request that succeeds. The socket is recycled
4573 // after use.
4574 request[0].method = "GET";
4575 request[0].url = GURL("http://www.google.com/");
4576 request[0].load_flags = 0;
4577 // Transaction 2: a POST request. Reuses the socket kept alive from
4578 // transaction 1. The first attempts fails when writing the POST data.
4579 // This causes the transaction to retry with a new socket. The second
4580 // attempt succeeds.
4581 request[1].method = "POST";
4582 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274583 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514584 request[1].load_flags = 0;
4585
[email protected]bb88e1d32013-05-03 23:11:074586 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514587
4588 // The first socket is used for transaction 1 and the first attempt of
4589 // transaction 2.
4590
4591 // The response of transaction 1.
4592 MockRead data_reads1[] = {
4593 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4594 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064595 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514596 };
4597 // The mock write results of transaction 1 and the first attempt of
4598 // transaction 2.
4599 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064600 MockWrite(SYNCHRONOUS, 64), // GET
4601 MockWrite(SYNCHRONOUS, 93), // POST
4602 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514603 };
[email protected]31a2bfe2010-02-09 08:03:394604 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4605 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514606
4607 // The second socket is used for the second attempt of transaction 2.
4608
4609 // The response of transaction 2.
4610 MockRead data_reads2[] = {
4611 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4612 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064613 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514614 };
4615 // The mock write results of the second attempt of transaction 2.
4616 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064617 MockWrite(SYNCHRONOUS, 93), // POST
4618 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514619 };
[email protected]31a2bfe2010-02-09 08:03:394620 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4621 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514622
[email protected]bb88e1d32013-05-03 23:11:074623 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4624 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514625
4626 const char* kExpectedResponseData[] = {
4627 "hello world", "welcome"
4628 };
4629
4630 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424631 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504632 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514633
[email protected]49639fa2011-12-20 23:22:414634 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514635
[email protected]49639fa2011-12-20 23:22:414636 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424637 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514638
4639 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424640 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514641
[email protected]1c773ea12009-04-28 19:58:424642 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504643 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514644
[email protected]90499482013-06-01 00:39:504645 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514646 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4647
4648 std::string response_data;
4649 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424650 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514651 EXPECT_EQ(kExpectedResponseData[i], response_data);
4652 }
4653}
[email protected]f9ee6b52008-11-08 06:46:234654
4655// Test the request-challenge-retry sequence for basic auth when there is
4656// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164657// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024658TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424659 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234660 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294661 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414662 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294663
[email protected]3fe8d2f82013-10-17 08:56:074664 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274665 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074666 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274667
[email protected]a97cca42009-08-14 01:00:294668 // The password contains an escaped character -- for this test to pass it
4669 // will need to be unescaped by HttpNetworkTransaction.
4670 EXPECT_EQ("b%40r", request.url.password());
4671
[email protected]f9ee6b52008-11-08 06:46:234672 MockWrite data_writes1[] = {
4673 MockWrite("GET / HTTP/1.1\r\n"
4674 "Host: www.google.com\r\n"
4675 "Connection: keep-alive\r\n\r\n"),
4676 };
4677
4678 MockRead data_reads1[] = {
4679 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4680 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4681 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064682 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234683 };
4684
[email protected]2262e3a2012-05-22 16:08:164685 // After the challenge above, the transaction will be restarted using the
4686 // identity from the url (foo, b@r) to answer the challenge.
4687 MockWrite data_writes2[] = {
4688 MockWrite("GET / HTTP/1.1\r\n"
4689 "Host: www.google.com\r\n"
4690 "Connection: keep-alive\r\n"
4691 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4692 };
4693
4694 MockRead data_reads2[] = {
4695 MockRead("HTTP/1.0 200 OK\r\n"),
4696 MockRead("Content-Length: 100\r\n\r\n"),
4697 MockRead(SYNCHRONOUS, OK),
4698 };
4699
[email protected]31a2bfe2010-02-09 08:03:394700 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4701 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164702 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4703 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074704 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4705 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234706
[email protected]49639fa2011-12-20 23:22:414707 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414708 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424709 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234710 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424711 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164712 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4713
4714 TestCompletionCallback callback2;
4715 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4716 EXPECT_EQ(ERR_IO_PENDING, rv);
4717 rv = callback2.WaitForResult();
4718 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224719 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4720
[email protected]2262e3a2012-05-22 16:08:164721 const HttpResponseInfo* response = trans->GetResponseInfo();
4722 ASSERT_TRUE(response != NULL);
4723
4724 // There is no challenge info, since the identity in URL worked.
4725 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4726
4727 EXPECT_EQ(100, response->headers->GetContentLength());
4728
4729 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344730 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164731}
4732
4733// Test the request-challenge-retry sequence for basic auth when there is an
4734// incorrect identity in the URL. The identity from the URL should be used only
4735// once.
[email protected]23e482282013-06-14 16:08:024736TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164737 HttpRequestInfo request;
4738 request.method = "GET";
4739 // Note: the URL has a username:password in it. The password "baz" is
4740 // wrong (should be "bar").
4741 request.url = GURL("http://foo:[email protected]/");
4742
4743 request.load_flags = LOAD_NORMAL;
4744
[email protected]3fe8d2f82013-10-17 08:56:074745 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:164746 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074747 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:164748
4749 MockWrite data_writes1[] = {
4750 MockWrite("GET / HTTP/1.1\r\n"
4751 "Host: www.google.com\r\n"
4752 "Connection: keep-alive\r\n\r\n"),
4753 };
4754
4755 MockRead data_reads1[] = {
4756 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4757 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4758 MockRead("Content-Length: 10\r\n\r\n"),
4759 MockRead(SYNCHRONOUS, ERR_FAILED),
4760 };
4761
4762 // After the challenge above, the transaction will be restarted using the
4763 // identity from the url (foo, baz) to answer the challenge.
4764 MockWrite data_writes2[] = {
4765 MockWrite("GET / HTTP/1.1\r\n"
4766 "Host: www.google.com\r\n"
4767 "Connection: keep-alive\r\n"
4768 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4769 };
4770
4771 MockRead data_reads2[] = {
4772 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4773 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4774 MockRead("Content-Length: 10\r\n\r\n"),
4775 MockRead(SYNCHRONOUS, ERR_FAILED),
4776 };
4777
4778 // After the challenge above, the transaction will be restarted using the
4779 // identity supplied by the user (foo, bar) to answer the challenge.
4780 MockWrite data_writes3[] = {
4781 MockWrite("GET / HTTP/1.1\r\n"
4782 "Host: www.google.com\r\n"
4783 "Connection: keep-alive\r\n"
4784 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4785 };
4786
4787 MockRead data_reads3[] = {
4788 MockRead("HTTP/1.0 200 OK\r\n"),
4789 MockRead("Content-Length: 100\r\n\r\n"),
4790 MockRead(SYNCHRONOUS, OK),
4791 };
4792
4793 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4794 data_writes1, arraysize(data_writes1));
4795 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4796 data_writes2, arraysize(data_writes2));
4797 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4798 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074799 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4800 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4801 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:164802
4803 TestCompletionCallback callback1;
4804
4805 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4806 EXPECT_EQ(ERR_IO_PENDING, rv);
4807
4808 rv = callback1.WaitForResult();
4809 EXPECT_EQ(OK, rv);
4810
4811 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4812 TestCompletionCallback callback2;
4813 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4814 EXPECT_EQ(ERR_IO_PENDING, rv);
4815 rv = callback2.WaitForResult();
4816 EXPECT_EQ(OK, rv);
4817 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4818
4819 const HttpResponseInfo* response = trans->GetResponseInfo();
4820 ASSERT_TRUE(response != NULL);
4821 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4822
4823 TestCompletionCallback callback3;
4824 rv = trans->RestartWithAuth(
4825 AuthCredentials(kFoo, kBar), callback3.callback());
4826 EXPECT_EQ(ERR_IO_PENDING, rv);
4827 rv = callback3.WaitForResult();
4828 EXPECT_EQ(OK, rv);
4829 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4830
4831 response = trans->GetResponseInfo();
4832 ASSERT_TRUE(response != NULL);
4833
4834 // There is no challenge info, since the identity worked.
4835 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4836
4837 EXPECT_EQ(100, response->headers->GetContentLength());
4838
[email protected]ea9dc9a2009-09-05 00:43:324839 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344840 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:324841}
4842
[email protected]2217aa22013-10-11 03:03:544843
4844// Test the request-challenge-retry sequence for basic auth when there is a
4845// correct identity in the URL, but its use is being suppressed. The identity
4846// from the URL should never be used.
4847TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
4848 HttpRequestInfo request;
4849 request.method = "GET";
4850 request.url = GURL("http://foo:[email protected]/");
4851 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
4852
[email protected]3fe8d2f82013-10-17 08:56:074853 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:544854 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074855 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:544856
4857 MockWrite data_writes1[] = {
4858 MockWrite("GET / HTTP/1.1\r\n"
4859 "Host: www.google.com\r\n"
4860 "Connection: keep-alive\r\n\r\n"),
4861 };
4862
4863 MockRead data_reads1[] = {
4864 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4865 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4866 MockRead("Content-Length: 10\r\n\r\n"),
4867 MockRead(SYNCHRONOUS, ERR_FAILED),
4868 };
4869
4870 // After the challenge above, the transaction will be restarted using the
4871 // identity supplied by the user, not the one in the URL, to answer the
4872 // challenge.
4873 MockWrite data_writes3[] = {
4874 MockWrite("GET / HTTP/1.1\r\n"
4875 "Host: www.google.com\r\n"
4876 "Connection: keep-alive\r\n"
4877 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4878 };
4879
4880 MockRead data_reads3[] = {
4881 MockRead("HTTP/1.0 200 OK\r\n"),
4882 MockRead("Content-Length: 100\r\n\r\n"),
4883 MockRead(SYNCHRONOUS, OK),
4884 };
4885
4886 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4887 data_writes1, arraysize(data_writes1));
4888 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4889 data_writes3, arraysize(data_writes3));
4890 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4891 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4892
4893 TestCompletionCallback callback1;
4894 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4895 EXPECT_EQ(ERR_IO_PENDING, rv);
4896 rv = callback1.WaitForResult();
4897 EXPECT_EQ(OK, rv);
4898 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4899
4900 const HttpResponseInfo* response = trans->GetResponseInfo();
4901 ASSERT_TRUE(response != NULL);
4902 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4903
4904 TestCompletionCallback callback3;
4905 rv = trans->RestartWithAuth(
4906 AuthCredentials(kFoo, kBar), callback3.callback());
4907 EXPECT_EQ(ERR_IO_PENDING, rv);
4908 rv = callback3.WaitForResult();
4909 EXPECT_EQ(OK, rv);
4910 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4911
4912 response = trans->GetResponseInfo();
4913 ASSERT_TRUE(response != NULL);
4914
4915 // There is no challenge info, since the identity worked.
4916 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4917 EXPECT_EQ(100, response->headers->GetContentLength());
4918
4919 // Empty the current queue.
4920 base::MessageLoop::current()->RunUntilIdle();
4921}
4922
[email protected]f9ee6b52008-11-08 06:46:234923// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:024924TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:074925 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:234926
4927 // Transaction 1: authenticate (foo, bar) on MyRealm1
4928 {
[email protected]1c773ea12009-04-28 19:58:424929 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234930 request.method = "GET";
4931 request.url = GURL("http://www.google.com/x/y/z");
4932 request.load_flags = 0;
4933
[email protected]262eec82013-03-19 21:01:364934 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504935 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274936
[email protected]f9ee6b52008-11-08 06:46:234937 MockWrite data_writes1[] = {
4938 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4939 "Host: www.google.com\r\n"
4940 "Connection: keep-alive\r\n\r\n"),
4941 };
4942
4943 MockRead data_reads1[] = {
4944 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4945 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4946 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064947 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234948 };
4949
4950 // Resend with authorization (username=foo, password=bar)
4951 MockWrite data_writes2[] = {
4952 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4953 "Host: www.google.com\r\n"
4954 "Connection: keep-alive\r\n"
4955 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4956 };
4957
4958 // Sever accepts the authorization.
4959 MockRead data_reads2[] = {
4960 MockRead("HTTP/1.0 200 OK\r\n"),
4961 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064962 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234963 };
4964
[email protected]31a2bfe2010-02-09 08:03:394965 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4966 data_writes1, arraysize(data_writes1));
4967 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4968 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074969 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4970 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234971
[email protected]49639fa2011-12-20 23:22:414972 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234973
[email protected]49639fa2011-12-20 23:22:414974 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424975 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234976
4977 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424978 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234979
[email protected]1c773ea12009-04-28 19:58:424980 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504981 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044982 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:234983
[email protected]49639fa2011-12-20 23:22:414984 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234985
[email protected]49639fa2011-12-20 23:22:414986 rv = trans->RestartWithAuth(
4987 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424988 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234989
4990 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424991 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234992
4993 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504994 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234995 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4996 EXPECT_EQ(100, response->headers->GetContentLength());
4997 }
4998
4999 // ------------------------------------------------------------------------
5000
5001 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5002 {
[email protected]1c773ea12009-04-28 19:58:425003 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235004 request.method = "GET";
5005 // Note that Transaction 1 was at /x/y/z, so this is in the same
5006 // protection space as MyRealm1.
5007 request.url = GURL("http://www.google.com/x/y/a/b");
5008 request.load_flags = 0;
5009
[email protected]262eec82013-03-19 21:01:365010 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505011 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275012
[email protected]f9ee6b52008-11-08 06:46:235013 MockWrite data_writes1[] = {
5014 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5015 "Host: www.google.com\r\n"
5016 "Connection: keep-alive\r\n"
5017 // Send preemptive authorization for MyRealm1
5018 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5019 };
5020
5021 // The server didn't like the preemptive authorization, and
5022 // challenges us for a different realm (MyRealm2).
5023 MockRead data_reads1[] = {
5024 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5025 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5026 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065027 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235028 };
5029
5030 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5031 MockWrite data_writes2[] = {
5032 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5033 "Host: www.google.com\r\n"
5034 "Connection: keep-alive\r\n"
5035 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5036 };
5037
5038 // Sever accepts the authorization.
5039 MockRead data_reads2[] = {
5040 MockRead("HTTP/1.0 200 OK\r\n"),
5041 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065042 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235043 };
5044
[email protected]31a2bfe2010-02-09 08:03:395045 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5046 data_writes1, arraysize(data_writes1));
5047 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5048 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075049 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5050 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235051
[email protected]49639fa2011-12-20 23:22:415052 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235053
[email protected]49639fa2011-12-20 23:22:415054 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425055 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235056
5057 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425058 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235059
[email protected]1c773ea12009-04-28 19:58:425060 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505061 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045062 ASSERT_TRUE(response->auth_challenge.get());
5063 EXPECT_FALSE(response->auth_challenge->is_proxy);
5064 EXPECT_EQ("www.google.com:80",
5065 response->auth_challenge->challenger.ToString());
5066 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5067 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235068
[email protected]49639fa2011-12-20 23:22:415069 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235070
[email protected]49639fa2011-12-20 23:22:415071 rv = trans->RestartWithAuth(
5072 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425073 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235074
5075 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425076 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235077
5078 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505079 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235080 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5081 EXPECT_EQ(100, response->headers->GetContentLength());
5082 }
5083
5084 // ------------------------------------------------------------------------
5085
5086 // Transaction 3: Resend a request in MyRealm's protection space --
5087 // succeed with preemptive authorization.
5088 {
[email protected]1c773ea12009-04-28 19:58:425089 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235090 request.method = "GET";
5091 request.url = GURL("http://www.google.com/x/y/z2");
5092 request.load_flags = 0;
5093
[email protected]262eec82013-03-19 21:01:365094 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505095 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275096
[email protected]f9ee6b52008-11-08 06:46:235097 MockWrite data_writes1[] = {
5098 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5099 "Host: www.google.com\r\n"
5100 "Connection: keep-alive\r\n"
5101 // The authorization for MyRealm1 gets sent preemptively
5102 // (since the url is in the same protection space)
5103 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5104 };
5105
5106 // Sever accepts the preemptive authorization
5107 MockRead data_reads1[] = {
5108 MockRead("HTTP/1.0 200 OK\r\n"),
5109 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065110 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235111 };
5112
[email protected]31a2bfe2010-02-09 08:03:395113 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5114 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075115 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235116
[email protected]49639fa2011-12-20 23:22:415117 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235118
[email protected]49639fa2011-12-20 23:22:415119 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425120 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235121
5122 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425123 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235124
[email protected]1c773ea12009-04-28 19:58:425125 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505126 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235127
5128 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5129 EXPECT_EQ(100, response->headers->GetContentLength());
5130 }
5131
5132 // ------------------------------------------------------------------------
5133
5134 // Transaction 4: request another URL in MyRealm (however the
5135 // url is not known to belong to the protection space, so no pre-auth).
5136 {
[email protected]1c773ea12009-04-28 19:58:425137 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235138 request.method = "GET";
5139 request.url = GURL("http://www.google.com/x/1");
5140 request.load_flags = 0;
5141
[email protected]262eec82013-03-19 21:01:365142 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505143 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275144
[email protected]f9ee6b52008-11-08 06:46:235145 MockWrite data_writes1[] = {
5146 MockWrite("GET /x/1 HTTP/1.1\r\n"
5147 "Host: www.google.com\r\n"
5148 "Connection: keep-alive\r\n\r\n"),
5149 };
5150
5151 MockRead data_reads1[] = {
5152 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5153 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5154 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065155 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235156 };
5157
5158 // Resend with authorization from MyRealm's cache.
5159 MockWrite data_writes2[] = {
5160 MockWrite("GET /x/1 HTTP/1.1\r\n"
5161 "Host: www.google.com\r\n"
5162 "Connection: keep-alive\r\n"
5163 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5164 };
5165
5166 // Sever accepts the authorization.
5167 MockRead data_reads2[] = {
5168 MockRead("HTTP/1.0 200 OK\r\n"),
5169 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065170 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235171 };
5172
[email protected]31a2bfe2010-02-09 08:03:395173 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5174 data_writes1, arraysize(data_writes1));
5175 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5176 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075177 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5178 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235179
[email protected]49639fa2011-12-20 23:22:415180 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235181
[email protected]49639fa2011-12-20 23:22:415182 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425183 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235184
5185 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425186 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235187
[email protected]0757e7702009-03-27 04:00:225188 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415189 TestCompletionCallback callback2;
5190 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425191 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225192 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425193 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225194 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5195
[email protected]1c773ea12009-04-28 19:58:425196 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505197 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235198 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5199 EXPECT_EQ(100, response->headers->GetContentLength());
5200 }
5201
5202 // ------------------------------------------------------------------------
5203
5204 // Transaction 5: request a URL in MyRealm, but the server rejects the
5205 // cached identity. Should invalidate and re-prompt.
5206 {
[email protected]1c773ea12009-04-28 19:58:425207 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235208 request.method = "GET";
5209 request.url = GURL("http://www.google.com/p/q/t");
5210 request.load_flags = 0;
5211
[email protected]262eec82013-03-19 21:01:365212 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505213 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275214
[email protected]f9ee6b52008-11-08 06:46:235215 MockWrite data_writes1[] = {
5216 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5217 "Host: www.google.com\r\n"
5218 "Connection: keep-alive\r\n\r\n"),
5219 };
5220
5221 MockRead data_reads1[] = {
5222 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5223 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5224 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065225 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235226 };
5227
5228 // Resend with authorization from cache for MyRealm.
5229 MockWrite data_writes2[] = {
5230 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5231 "Host: www.google.com\r\n"
5232 "Connection: keep-alive\r\n"
5233 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5234 };
5235
5236 // Sever rejects the authorization.
5237 MockRead data_reads2[] = {
5238 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5239 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5240 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065241 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235242 };
5243
5244 // At this point we should prompt for new credentials for MyRealm.
5245 // Restart with username=foo3, password=foo4.
5246 MockWrite data_writes3[] = {
5247 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5248 "Host: www.google.com\r\n"
5249 "Connection: keep-alive\r\n"
5250 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5251 };
5252
5253 // Sever accepts the authorization.
5254 MockRead data_reads3[] = {
5255 MockRead("HTTP/1.0 200 OK\r\n"),
5256 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065257 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235258 };
5259
[email protected]31a2bfe2010-02-09 08:03:395260 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5261 data_writes1, arraysize(data_writes1));
5262 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5263 data_writes2, arraysize(data_writes2));
5264 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5265 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075266 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5267 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5268 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235269
[email protected]49639fa2011-12-20 23:22:415270 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235271
[email protected]49639fa2011-12-20 23:22:415272 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425273 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235274
5275 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425276 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235277
[email protected]0757e7702009-03-27 04:00:225278 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415279 TestCompletionCallback callback2;
5280 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425281 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225282 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425283 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225284 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5285
[email protected]1c773ea12009-04-28 19:58:425286 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505287 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045288 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235289
[email protected]49639fa2011-12-20 23:22:415290 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235291
[email protected]49639fa2011-12-20 23:22:415292 rv = trans->RestartWithAuth(
5293 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425294 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235295
[email protected]0757e7702009-03-27 04:00:225296 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425297 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235298
5299 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505300 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235301 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5302 EXPECT_EQ(100, response->headers->GetContentLength());
5303 }
5304}
[email protected]89ceba9a2009-03-21 03:46:065305
[email protected]3c32c5f2010-05-18 15:18:125306// Tests that nonce count increments when multiple auth attempts
5307// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025308TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445309 HttpAuthHandlerDigest::Factory* digest_factory =
5310 new HttpAuthHandlerDigest::Factory();
5311 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5312 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5313 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075314 session_deps_.http_auth_handler_factory.reset(digest_factory);
5315 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125316
5317 // Transaction 1: authenticate (foo, bar) on MyRealm1
5318 {
[email protected]3c32c5f2010-05-18 15:18:125319 HttpRequestInfo request;
5320 request.method = "GET";
5321 request.url = GURL("http://www.google.com/x/y/z");
5322 request.load_flags = 0;
5323
[email protected]262eec82013-03-19 21:01:365324 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275326
[email protected]3c32c5f2010-05-18 15:18:125327 MockWrite data_writes1[] = {
5328 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5329 "Host: www.google.com\r\n"
5330 "Connection: keep-alive\r\n\r\n"),
5331 };
5332
5333 MockRead data_reads1[] = {
5334 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5335 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5336 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065337 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125338 };
5339
5340 // Resend with authorization (username=foo, password=bar)
5341 MockWrite data_writes2[] = {
5342 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5343 "Host: www.google.com\r\n"
5344 "Connection: keep-alive\r\n"
5345 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5346 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5347 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5348 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5349 };
5350
5351 // Sever accepts the authorization.
5352 MockRead data_reads2[] = {
5353 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065354 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125355 };
5356
5357 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5358 data_writes1, arraysize(data_writes1));
5359 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5360 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075361 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5362 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125363
[email protected]49639fa2011-12-20 23:22:415364 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125365
[email protected]49639fa2011-12-20 23:22:415366 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125367 EXPECT_EQ(ERR_IO_PENDING, rv);
5368
5369 rv = callback1.WaitForResult();
5370 EXPECT_EQ(OK, rv);
5371
5372 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505373 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045374 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125375
[email protected]49639fa2011-12-20 23:22:415376 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125377
[email protected]49639fa2011-12-20 23:22:415378 rv = trans->RestartWithAuth(
5379 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125380 EXPECT_EQ(ERR_IO_PENDING, rv);
5381
5382 rv = callback2.WaitForResult();
5383 EXPECT_EQ(OK, rv);
5384
5385 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505386 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125387 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5388 }
5389
5390 // ------------------------------------------------------------------------
5391
5392 // Transaction 2: Request another resource in digestive's protection space.
5393 // This will preemptively add an Authorization header which should have an
5394 // "nc" value of 2 (as compared to 1 in the first use.
5395 {
[email protected]3c32c5f2010-05-18 15:18:125396 HttpRequestInfo request;
5397 request.method = "GET";
5398 // Note that Transaction 1 was at /x/y/z, so this is in the same
5399 // protection space as digest.
5400 request.url = GURL("http://www.google.com/x/y/a/b");
5401 request.load_flags = 0;
5402
[email protected]262eec82013-03-19 21:01:365403 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275405
[email protected]3c32c5f2010-05-18 15:18:125406 MockWrite data_writes1[] = {
5407 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5408 "Host: www.google.com\r\n"
5409 "Connection: keep-alive\r\n"
5410 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5411 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5412 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5413 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5414 };
5415
5416 // Sever accepts the authorization.
5417 MockRead data_reads1[] = {
5418 MockRead("HTTP/1.0 200 OK\r\n"),
5419 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065420 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125421 };
5422
5423 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5424 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075425 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125426
[email protected]49639fa2011-12-20 23:22:415427 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125428
[email protected]49639fa2011-12-20 23:22:415429 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125430 EXPECT_EQ(ERR_IO_PENDING, rv);
5431
5432 rv = callback1.WaitForResult();
5433 EXPECT_EQ(OK, rv);
5434
5435 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505436 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125437 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5438 }
5439}
5440
[email protected]89ceba9a2009-03-21 03:46:065441// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025442TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065443 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075444 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405445 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065447
5448 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065449 trans->read_buf_ = new IOBuffer(15);
5450 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205451 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065452
5453 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145454 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575455 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085456 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575457 response->response_time = base::Time::Now();
5458 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065459
5460 { // Setup state for response_.vary_data
5461 HttpRequestInfo request;
5462 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5463 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275464 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435465 request.extra_headers.SetHeader("Foo", "1");
5466 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505467 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065468 }
5469
5470 // Cause the above state to be reset.
5471 trans->ResetStateForRestart();
5472
5473 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075474 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065475 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205476 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575477 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5478 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045479 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085480 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575481 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065482}
5483
[email protected]bacff652009-03-31 17:50:335484// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025485TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335486 HttpRequestInfo request;
5487 request.method = "GET";
5488 request.url = GURL("https://www.google.com/");
5489 request.load_flags = 0;
5490
[email protected]3fe8d2f82013-10-17 08:56:075491 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275492 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075493 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275494
[email protected]bacff652009-03-31 17:50:335495 MockWrite data_writes[] = {
5496 MockWrite("GET / HTTP/1.1\r\n"
5497 "Host: www.google.com\r\n"
5498 "Connection: keep-alive\r\n\r\n"),
5499 };
5500
5501 MockRead data_reads[] = {
5502 MockRead("HTTP/1.0 200 OK\r\n"),
5503 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5504 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065505 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335506 };
5507
[email protected]5ecc992a42009-11-11 01:41:595508 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395509 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5510 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065511 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5512 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335513
[email protected]bb88e1d32013-05-03 23:11:075514 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5515 session_deps_.socket_factory->AddSocketDataProvider(&data);
5516 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335518
[email protected]49639fa2011-12-20 23:22:415519 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335520
[email protected]49639fa2011-12-20 23:22:415521 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335522 EXPECT_EQ(ERR_IO_PENDING, rv);
5523
5524 rv = callback.WaitForResult();
5525 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5526
[email protected]49639fa2011-12-20 23:22:415527 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335528 EXPECT_EQ(ERR_IO_PENDING, rv);
5529
5530 rv = callback.WaitForResult();
5531 EXPECT_EQ(OK, rv);
5532
5533 const HttpResponseInfo* response = trans->GetResponseInfo();
5534
[email protected]fe2255a2011-09-20 19:37:505535 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335536 EXPECT_EQ(100, response->headers->GetContentLength());
5537}
5538
5539// Test HTTPS connections to a site with a bad certificate, going through a
5540// proxy
[email protected]23e482282013-06-14 16:08:025541TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075542 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335543
5544 HttpRequestInfo request;
5545 request.method = "GET";
5546 request.url = GURL("https://www.google.com/");
5547 request.load_flags = 0;
5548
5549 MockWrite proxy_writes[] = {
5550 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455551 "Host: www.google.com\r\n"
5552 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335553 };
5554
5555 MockRead proxy_reads[] = {
5556 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065557 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335558 };
5559
5560 MockWrite data_writes[] = {
5561 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455562 "Host: www.google.com\r\n"
5563 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335564 MockWrite("GET / HTTP/1.1\r\n"
5565 "Host: www.google.com\r\n"
5566 "Connection: keep-alive\r\n\r\n"),
5567 };
5568
5569 MockRead data_reads[] = {
5570 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5571 MockRead("HTTP/1.0 200 OK\r\n"),
5572 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5573 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065574 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335575 };
5576
[email protected]31a2bfe2010-02-09 08:03:395577 StaticSocketDataProvider ssl_bad_certificate(
5578 proxy_reads, arraysize(proxy_reads),
5579 proxy_writes, arraysize(proxy_writes));
5580 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5581 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065582 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5583 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335584
[email protected]bb88e1d32013-05-03 23:11:075585 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5586 session_deps_.socket_factory->AddSocketDataProvider(&data);
5587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5588 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335589
[email protected]49639fa2011-12-20 23:22:415590 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335591
5592 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075593 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335594
[email protected]3fe8d2f82013-10-17 08:56:075595 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405596 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075597 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:335598
[email protected]49639fa2011-12-20 23:22:415599 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335600 EXPECT_EQ(ERR_IO_PENDING, rv);
5601
5602 rv = callback.WaitForResult();
5603 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5604
[email protected]49639fa2011-12-20 23:22:415605 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335606 EXPECT_EQ(ERR_IO_PENDING, rv);
5607
5608 rv = callback.WaitForResult();
5609 EXPECT_EQ(OK, rv);
5610
5611 const HttpResponseInfo* response = trans->GetResponseInfo();
5612
[email protected]fe2255a2011-09-20 19:37:505613 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335614 EXPECT_EQ(100, response->headers->GetContentLength());
5615 }
5616}
5617
[email protected]2df19bb2010-08-25 20:13:465618
5619// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025620TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075621 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205622 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5623 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075624 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465625
5626 HttpRequestInfo request;
5627 request.method = "GET";
5628 request.url = GURL("https://www.google.com/");
5629 request.load_flags = 0;
5630
5631 MockWrite data_writes[] = {
5632 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5633 "Host: www.google.com\r\n"
5634 "Proxy-Connection: keep-alive\r\n\r\n"),
5635 MockWrite("GET / HTTP/1.1\r\n"
5636 "Host: www.google.com\r\n"
5637 "Connection: keep-alive\r\n\r\n"),
5638 };
5639
5640 MockRead data_reads[] = {
5641 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5642 MockRead("HTTP/1.1 200 OK\r\n"),
5643 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5644 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065645 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465646 };
5647
5648 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5649 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065650 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5651 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465652
[email protected]bb88e1d32013-05-03 23:11:075653 session_deps_.socket_factory->AddSocketDataProvider(&data);
5654 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5655 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465656
[email protected]49639fa2011-12-20 23:22:415657 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465658
[email protected]3fe8d2f82013-10-17 08:56:075659 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465660 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:465662
[email protected]49639fa2011-12-20 23:22:415663 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465664 EXPECT_EQ(ERR_IO_PENDING, rv);
5665
5666 rv = callback.WaitForResult();
5667 EXPECT_EQ(OK, rv);
5668 const HttpResponseInfo* response = trans->GetResponseInfo();
5669
[email protected]fe2255a2011-09-20 19:37:505670 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465671
5672 EXPECT_TRUE(response->headers->IsKeepAlive());
5673 EXPECT_EQ(200, response->headers->response_code());
5674 EXPECT_EQ(100, response->headers->GetContentLength());
5675 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205676
5677 LoadTimingInfo load_timing_info;
5678 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5679 TestLoadTimingNotReusedWithPac(load_timing_info,
5680 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465681}
5682
[email protected]511f6f52010-12-17 03:58:295683// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025684TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075685 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205686 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5687 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075688 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295689
5690 HttpRequestInfo request;
5691 request.method = "GET";
5692 request.url = GURL("https://www.google.com/");
5693 request.load_flags = 0;
5694
5695 MockWrite data_writes[] = {
5696 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5697 "Host: www.google.com\r\n"
5698 "Proxy-Connection: keep-alive\r\n\r\n"),
5699 };
5700
5701 MockRead data_reads[] = {
5702 MockRead("HTTP/1.1 302 Redirect\r\n"),
5703 MockRead("Location: http://login.example.com/\r\n"),
5704 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065705 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295706 };
5707
5708 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5709 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065710 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295711
[email protected]bb88e1d32013-05-03 23:11:075712 session_deps_.socket_factory->AddSocketDataProvider(&data);
5713 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295714
[email protected]49639fa2011-12-20 23:22:415715 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295716
[email protected]3fe8d2f82013-10-17 08:56:075717 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295718 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075719 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295720
[email protected]49639fa2011-12-20 23:22:415721 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295722 EXPECT_EQ(ERR_IO_PENDING, rv);
5723
5724 rv = callback.WaitForResult();
5725 EXPECT_EQ(OK, rv);
5726 const HttpResponseInfo* response = trans->GetResponseInfo();
5727
[email protected]fe2255a2011-09-20 19:37:505728 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295729
5730 EXPECT_EQ(302, response->headers->response_code());
5731 std::string url;
5732 EXPECT_TRUE(response->headers->IsRedirect(&url));
5733 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205734
5735 // In the case of redirects from proxies, HttpNetworkTransaction returns
5736 // timing for the proxy connection instead of the connection to the host,
5737 // and no send / receive times.
5738 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5739 LoadTimingInfo load_timing_info;
5740 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5741
5742 EXPECT_FALSE(load_timing_info.socket_reused);
5743 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5744
5745 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5746 EXPECT_LE(load_timing_info.proxy_resolve_start,
5747 load_timing_info.proxy_resolve_end);
5748 EXPECT_LE(load_timing_info.proxy_resolve_end,
5749 load_timing_info.connect_timing.connect_start);
5750 ExpectConnectTimingHasTimes(
5751 load_timing_info.connect_timing,
5752 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5753
5754 EXPECT_TRUE(load_timing_info.send_start.is_null());
5755 EXPECT_TRUE(load_timing_info.send_end.is_null());
5756 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:295757}
5758
5759// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025760TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075761 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295762 ProxyService::CreateFixed("https://proxy:70"));
5763
5764 HttpRequestInfo request;
5765 request.method = "GET";
5766 request.url = GURL("https://www.google.com/");
5767 request.load_flags = 0;
5768
[email protected]9075f51c2013-08-15 17:53:545769 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5770 LOWEST));
[email protected]c10b20852013-05-15 21:29:205771 scoped_ptr<SpdyFrame> goaway(
5772 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295773 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065774 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:125775 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295776 };
5777
5778 static const char* const kExtraHeaders[] = {
5779 "location",
5780 "http://login.example.com/",
5781 };
[email protected]ff98d7f02012-03-22 21:44:195782 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025783 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295784 arraysize(kExtraHeaders)/2, 1));
5785 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065786 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5787 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:295788 };
5789
[email protected]dd54bd82012-07-19 23:44:575790 DelayedSocketData data(
5791 1, // wait for one write to finish before reading.
5792 data_reads, arraysize(data_reads),
5793 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065794 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025795 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295796
[email protected]bb88e1d32013-05-03 23:11:075797 session_deps_.socket_factory->AddSocketDataProvider(&data);
5798 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295799
[email protected]49639fa2011-12-20 23:22:415800 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295801
[email protected]3fe8d2f82013-10-17 08:56:075802 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295803 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295805
[email protected]49639fa2011-12-20 23:22:415806 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295807 EXPECT_EQ(ERR_IO_PENDING, rv);
5808
5809 rv = callback.WaitForResult();
5810 EXPECT_EQ(OK, rv);
5811 const HttpResponseInfo* response = trans->GetResponseInfo();
5812
[email protected]fe2255a2011-09-20 19:37:505813 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295814
5815 EXPECT_EQ(302, response->headers->response_code());
5816 std::string url;
5817 EXPECT_TRUE(response->headers->IsRedirect(&url));
5818 EXPECT_EQ("http://login.example.com/", url);
5819}
5820
[email protected]4eddbc732012-08-09 05:40:175821// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025822TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175823 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075824 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295825 ProxyService::CreateFixed("https://proxy:70"));
5826
5827 HttpRequestInfo request;
5828 request.method = "GET";
5829 request.url = GURL("https://www.google.com/");
5830 request.load_flags = 0;
5831
5832 MockWrite data_writes[] = {
5833 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5834 "Host: www.google.com\r\n"
5835 "Proxy-Connection: keep-alive\r\n\r\n"),
5836 };
5837
5838 MockRead data_reads[] = {
5839 MockRead("HTTP/1.1 404 Not Found\r\n"),
5840 MockRead("Content-Length: 23\r\n\r\n"),
5841 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:065842 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295843 };
5844
5845 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5846 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065847 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295848
[email protected]bb88e1d32013-05-03 23:11:075849 session_deps_.socket_factory->AddSocketDataProvider(&data);
5850 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295851
[email protected]49639fa2011-12-20 23:22:415852 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295853
[email protected]3fe8d2f82013-10-17 08:56:075854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295855 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295857
[email protected]49639fa2011-12-20 23:22:415858 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295859 EXPECT_EQ(ERR_IO_PENDING, rv);
5860
5861 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175862 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295863
[email protected]4eddbc732012-08-09 05:40:175864 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295865}
5866
[email protected]4eddbc732012-08-09 05:40:175867// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025868TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175869 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075870 session_deps_.proxy_service.reset(
5871 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:295872
5873 HttpRequestInfo request;
5874 request.method = "GET";
5875 request.url = GURL("https://www.google.com/");
5876 request.load_flags = 0;
5877
[email protected]9075f51c2013-08-15 17:53:545878 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5879 LOWEST));
[email protected]c10b20852013-05-15 21:29:205880 scoped_ptr<SpdyFrame> rst(
5881 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295882 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065883 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175884 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295885 };
5886
5887 static const char* const kExtraHeaders[] = {
5888 "location",
5889 "http://login.example.com/",
5890 };
[email protected]ff98d7f02012-03-22 21:44:195891 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025892 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295893 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:195894 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:025895 spdy_util_.ConstructSpdyBodyFrame(
5896 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:295897 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065898 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5899 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175900 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:295901 };
5902
[email protected]dd54bd82012-07-19 23:44:575903 DelayedSocketData data(
5904 1, // wait for one write to finish before reading.
5905 data_reads, arraysize(data_reads),
5906 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065907 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025908 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295909
[email protected]bb88e1d32013-05-03 23:11:075910 session_deps_.socket_factory->AddSocketDataProvider(&data);
5911 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295912
[email protected]49639fa2011-12-20 23:22:415913 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295914
[email protected]3fe8d2f82013-10-17 08:56:075915 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295916 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295918
[email protected]49639fa2011-12-20 23:22:415919 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295920 EXPECT_EQ(ERR_IO_PENDING, rv);
5921
5922 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175923 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295924
[email protected]4eddbc732012-08-09 05:40:175925 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295926}
5927
[email protected]0c5fb722012-02-28 11:50:355928// Test the request-challenge-retry sequence for basic auth, through
5929// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:025930TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:355931 HttpRequestInfo request;
5932 request.method = "GET";
5933 request.url = GURL("https://www.google.com/");
5934 // when the no authentication data flag is set.
5935 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
5936
5937 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075938 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205939 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:295940 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075941 session_deps_.net_log = log.bound().net_log();
5942 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:355943
5944 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:545945 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5946 LOWEST));
[email protected]c10b20852013-05-15 21:29:205947 scoped_ptr<SpdyFrame> rst(
5948 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:355949
5950 // After calling trans->RestartWithAuth(), this is the request we should
5951 // be issuing -- the final header line contains the credentials.
5952 const char* const kAuthCredentials[] = {
5953 "proxy-authorization", "Basic Zm9vOmJhcg==",
5954 };
[email protected]fba2dbde2013-05-24 16:09:015955 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:545956 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:355957 // fetch https://www.google.com/ via HTTP
5958 const char get[] = "GET / HTTP/1.1\r\n"
5959 "Host: www.google.com\r\n"
5960 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:195961 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:025962 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:355963
5964 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:205965 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:215966 CreateMockWrite(*rst, 4, ASYNC),
5967 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:205968 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:355969 };
5970
5971 // The proxy responds to the connect with a 407, using a persistent
5972 // connection.
5973 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:025974 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
5975 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:355976 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
5977 };
5978
[email protected]ff98d7f02012-03-22 21:44:195979 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:235980 spdy_util_.ConstructSpdyControlFrame(NULL,
5981 0,
5982 false,
5983 1,
5984 LOWEST,
5985 SYN_REPLY,
5986 CONTROL_FLAG_NONE,
5987 kAuthChallenge,
5988 arraysize(kAuthChallenge),
5989 0));
[email protected]0c5fb722012-02-28 11:50:355990
[email protected]23e482282013-06-14 16:08:025991 scoped_ptr<SpdyFrame> conn_resp(
5992 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:355993 const char resp[] = "HTTP/1.1 200 OK\r\n"
5994 "Content-Length: 5\r\n\r\n";
5995
[email protected]ff98d7f02012-03-22 21:44:195996 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025997 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:195998 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:025999 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356000 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206001 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6002 CreateMockRead(*conn_resp, 6, ASYNC),
6003 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6004 CreateMockRead(*wrapped_body, 10, ASYNC),
6005 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356006 };
6007
[email protected]dd54bd82012-07-19 23:44:576008 OrderedSocketData spdy_data(
6009 spdy_reads, arraysize(spdy_reads),
6010 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076011 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356012 // Negotiate SPDY to the proxy
6013 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026014 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076015 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356016 // Vanilla SSL to the server
6017 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076018 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356019
6020 TestCompletionCallback callback1;
6021
[email protected]262eec82013-03-19 21:01:366022 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356024
6025 int rv = trans->Start(&request, callback1.callback(), log.bound());
6026 EXPECT_EQ(ERR_IO_PENDING, rv);
6027
6028 rv = callback1.WaitForResult();
6029 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576030 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356031 log.GetEntries(&entries);
6032 size_t pos = ExpectLogContainsSomewhere(
6033 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6034 NetLog::PHASE_NONE);
6035 ExpectLogContainsSomewhere(
6036 entries, pos,
6037 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6038 NetLog::PHASE_NONE);
6039
6040 const HttpResponseInfo* response = trans->GetResponseInfo();
6041 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506042 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356043 EXPECT_EQ(407, response->headers->response_code());
6044 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6045 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6046 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6047
6048 TestCompletionCallback callback2;
6049
6050 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6051 callback2.callback());
6052 EXPECT_EQ(ERR_IO_PENDING, rv);
6053
6054 rv = callback2.WaitForResult();
6055 EXPECT_EQ(OK, rv);
6056
6057 response = trans->GetResponseInfo();
6058 ASSERT_TRUE(response != NULL);
6059
6060 EXPECT_TRUE(response->headers->IsKeepAlive());
6061 EXPECT_EQ(200, response->headers->response_code());
6062 EXPECT_EQ(5, response->headers->GetContentLength());
6063 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6064
6065 // The password prompt info should not be set.
6066 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6067
[email protected]029c83b62013-01-24 05:28:206068 LoadTimingInfo load_timing_info;
6069 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6070 TestLoadTimingNotReusedWithPac(load_timing_info,
6071 CONNECT_TIMING_HAS_SSL_TIMES);
6072
[email protected]0c5fb722012-02-28 11:50:356073 trans.reset();
6074 session->CloseAllConnections();
6075}
6076
[email protected]7c6f7ba2012-04-03 04:09:296077// Test that an explicitly trusted SPDY proxy can push a resource from an
6078// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026079TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296080 HttpRequestInfo request;
6081 HttpRequestInfo push_request;
6082
[email protected]7c6f7ba2012-04-03 04:09:296083 request.method = "GET";
6084 request.url = GURL("http://www.google.com/");
6085 push_request.method = "GET";
6086 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6087
[email protected]7c6f7ba2012-04-03 04:09:296088 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076089 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206090 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296091 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076092 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506093
6094 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076095 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506096
[email protected]bb88e1d32013-05-03 23:11:076097 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296098
[email protected]cdf8f7e72013-05-23 10:56:466099 scoped_ptr<SpdyFrame> stream1_syn(
6100 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296101
6102 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466103 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296104 };
6105
6106 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026107 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296108
6109 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026110 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296111
6112 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026113 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296114 0,
6115 2,
6116 1,
6117 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436118 const char kPushedData[] = "pushed";
6119 scoped_ptr<SpdyFrame> stream2_body(
6120 spdy_util_.ConstructSpdyBodyFrame(
6121 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296122
6123 MockRead spdy_reads[] = {
6124 CreateMockRead(*stream1_reply, 2, ASYNC),
6125 CreateMockRead(*stream2_syn, 3, ASYNC),
6126 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436127 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296128 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6129 };
6130
[email protected]dd54bd82012-07-19 23:44:576131 OrderedSocketData spdy_data(
6132 spdy_reads, arraysize(spdy_reads),
6133 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076134 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296135 // Negotiate SPDY to the proxy
6136 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026137 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076138 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296139
[email protected]262eec82013-03-19 21:01:366140 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296142 TestCompletionCallback callback;
6143 int rv = trans->Start(&request, callback.callback(), log.bound());
6144 EXPECT_EQ(ERR_IO_PENDING, rv);
6145
6146 rv = callback.WaitForResult();
6147 EXPECT_EQ(OK, rv);
6148 const HttpResponseInfo* response = trans->GetResponseInfo();
6149
[email protected]262eec82013-03-19 21:01:366150 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6152 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296153 EXPECT_EQ(ERR_IO_PENDING, rv);
6154
6155 rv = callback.WaitForResult();
6156 EXPECT_EQ(OK, rv);
6157 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6158
6159 ASSERT_TRUE(response != NULL);
6160 EXPECT_TRUE(response->headers->IsKeepAlive());
6161
6162 EXPECT_EQ(200, response->headers->response_code());
6163 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6164
6165 std::string response_data;
6166 rv = ReadTransaction(trans.get(), &response_data);
6167 EXPECT_EQ(OK, rv);
6168 EXPECT_EQ("hello!", response_data);
6169
[email protected]029c83b62013-01-24 05:28:206170 LoadTimingInfo load_timing_info;
6171 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6172 TestLoadTimingNotReusedWithPac(load_timing_info,
6173 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6174
[email protected]7c6f7ba2012-04-03 04:09:296175 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506176 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296177 EXPECT_EQ(200, push_response->headers->response_code());
6178
6179 rv = ReadTransaction(push_trans.get(), &response_data);
6180 EXPECT_EQ(OK, rv);
6181 EXPECT_EQ("pushed", response_data);
6182
[email protected]029c83b62013-01-24 05:28:206183 LoadTimingInfo push_load_timing_info;
6184 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6185 TestLoadTimingReusedWithPac(push_load_timing_info);
6186 // The transactions should share a socket ID, despite being for different
6187 // origins.
6188 EXPECT_EQ(load_timing_info.socket_log_id,
6189 push_load_timing_info.socket_log_id);
6190
[email protected]7c6f7ba2012-04-03 04:09:296191 trans.reset();
6192 push_trans.reset();
6193 session->CloseAllConnections();
6194}
6195
[email protected]8c843192012-04-05 07:15:006196// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026197TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006198 HttpRequestInfo request;
6199
6200 request.method = "GET";
6201 request.url = GURL("http://www.google.com/");
6202
[email protected]8c843192012-04-05 07:15:006203 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076204 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006205 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296206 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076207 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506208
6209 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076210 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506211
[email protected]bb88e1d32013-05-03 23:11:076212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006213
[email protected]cdf8f7e72013-05-23 10:56:466214 scoped_ptr<SpdyFrame> stream1_syn(
6215 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006216
6217 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206218 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006219
6220 MockWrite spdy_writes[] = {
6221 CreateMockWrite(*stream1_syn, 1, ASYNC),
6222 CreateMockWrite(*push_rst, 4),
6223 };
6224
6225 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026226 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006227
6228 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026229 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006230
6231 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026232 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006233 0,
6234 2,
6235 1,
6236 "https://www.another-origin.com/foo.dat"));
6237
6238 MockRead spdy_reads[] = {
6239 CreateMockRead(*stream1_reply, 2, ASYNC),
6240 CreateMockRead(*stream2_syn, 3, ASYNC),
6241 CreateMockRead(*stream1_body, 5, ASYNC),
6242 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6243 };
6244
[email protected]dd54bd82012-07-19 23:44:576245 OrderedSocketData spdy_data(
6246 spdy_reads, arraysize(spdy_reads),
6247 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076248 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006249 // Negotiate SPDY to the proxy
6250 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026251 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076252 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006253
[email protected]262eec82013-03-19 21:01:366254 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006256 TestCompletionCallback callback;
6257 int rv = trans->Start(&request, callback.callback(), log.bound());
6258 EXPECT_EQ(ERR_IO_PENDING, rv);
6259
6260 rv = callback.WaitForResult();
6261 EXPECT_EQ(OK, rv);
6262 const HttpResponseInfo* response = trans->GetResponseInfo();
6263
6264 ASSERT_TRUE(response != NULL);
6265 EXPECT_TRUE(response->headers->IsKeepAlive());
6266
6267 EXPECT_EQ(200, response->headers->response_code());
6268 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6269
6270 std::string response_data;
6271 rv = ReadTransaction(trans.get(), &response_data);
6272 EXPECT_EQ(OK, rv);
6273 EXPECT_EQ("hello!", response_data);
6274
6275 trans.reset();
6276 session->CloseAllConnections();
6277}
6278
[email protected]2df19bb2010-08-25 20:13:466279// Test HTTPS connections to a site with a bad certificate, going through an
6280// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026281TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076282 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116283 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466284
6285 HttpRequestInfo request;
6286 request.method = "GET";
6287 request.url = GURL("https://www.google.com/");
6288 request.load_flags = 0;
6289
6290 // Attempt to fetch the URL from a server with a bad cert
6291 MockWrite bad_cert_writes[] = {
6292 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6293 "Host: www.google.com\r\n"
6294 "Proxy-Connection: keep-alive\r\n\r\n"),
6295 };
6296
6297 MockRead bad_cert_reads[] = {
6298 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066299 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466300 };
6301
6302 // Attempt to fetch the URL with a good cert
6303 MockWrite good_data_writes[] = {
6304 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6305 "Host: www.google.com\r\n"
6306 "Proxy-Connection: keep-alive\r\n\r\n"),
6307 MockWrite("GET / HTTP/1.1\r\n"
6308 "Host: www.google.com\r\n"
6309 "Connection: keep-alive\r\n\r\n"),
6310 };
6311
6312 MockRead good_cert_reads[] = {
6313 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6314 MockRead("HTTP/1.0 200 OK\r\n"),
6315 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6316 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066317 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466318 };
6319
6320 StaticSocketDataProvider ssl_bad_certificate(
6321 bad_cert_reads, arraysize(bad_cert_reads),
6322 bad_cert_writes, arraysize(bad_cert_writes));
6323 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6324 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066325 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6326 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466327
6328 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6330 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466332
6333 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6335 session_deps_.socket_factory->AddSocketDataProvider(&data);
6336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466337
[email protected]49639fa2011-12-20 23:22:416338 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466339
[email protected]3fe8d2f82013-10-17 08:56:076340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466341 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076342 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466343
[email protected]49639fa2011-12-20 23:22:416344 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466345 EXPECT_EQ(ERR_IO_PENDING, rv);
6346
6347 rv = callback.WaitForResult();
6348 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6349
[email protected]49639fa2011-12-20 23:22:416350 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466351 EXPECT_EQ(ERR_IO_PENDING, rv);
6352
6353 rv = callback.WaitForResult();
6354 EXPECT_EQ(OK, rv);
6355
6356 const HttpResponseInfo* response = trans->GetResponseInfo();
6357
[email protected]fe2255a2011-09-20 19:37:506358 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466359 EXPECT_EQ(100, response->headers->GetContentLength());
6360}
6361
[email protected]23e482282013-06-14 16:08:026362TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426363 HttpRequestInfo request;
6364 request.method = "GET";
6365 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436366 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6367 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426368
[email protected]3fe8d2f82013-10-17 08:56:076369 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276370 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076371 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276372
[email protected]1c773ea12009-04-28 19:58:426373 MockWrite data_writes[] = {
6374 MockWrite("GET / HTTP/1.1\r\n"
6375 "Host: www.google.com\r\n"
6376 "Connection: keep-alive\r\n"
6377 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6378 };
6379
6380 // Lastly, the server responds with the actual content.
6381 MockRead data_reads[] = {
6382 MockRead("HTTP/1.0 200 OK\r\n"),
6383 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6384 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066385 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426386 };
6387
[email protected]31a2bfe2010-02-09 08:03:396388 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6389 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076390 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426391
[email protected]49639fa2011-12-20 23:22:416392 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426393
[email protected]49639fa2011-12-20 23:22:416394 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426395 EXPECT_EQ(ERR_IO_PENDING, rv);
6396
6397 rv = callback.WaitForResult();
6398 EXPECT_EQ(OK, rv);
6399}
6400
[email protected]23e482282013-06-14 16:08:026401TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296402 HttpRequestInfo request;
6403 request.method = "GET";
6404 request.url = GURL("https://www.google.com/");
6405 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6406 "Chromium Ultra Awesome X Edition");
6407
[email protected]bb88e1d32013-05-03 23:11:076408 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076409 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276410 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076411 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276412
[email protected]da81f132010-08-18 23:39:296413 MockWrite data_writes[] = {
6414 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6415 "Host: www.google.com\r\n"
6416 "Proxy-Connection: keep-alive\r\n"
6417 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6418 };
6419 MockRead data_reads[] = {
6420 // Return an error, so the transaction stops here (this test isn't
6421 // interested in the rest).
6422 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6423 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6424 MockRead("Proxy-Connection: close\r\n\r\n"),
6425 };
6426
6427 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6428 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076429 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296430
[email protected]49639fa2011-12-20 23:22:416431 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296432
[email protected]49639fa2011-12-20 23:22:416433 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296434 EXPECT_EQ(ERR_IO_PENDING, rv);
6435
6436 rv = callback.WaitForResult();
6437 EXPECT_EQ(OK, rv);
6438}
6439
[email protected]23e482282013-06-14 16:08:026440TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426441 HttpRequestInfo request;
6442 request.method = "GET";
6443 request.url = GURL("http://www.google.com/");
6444 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166445 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6446 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426447
[email protected]3fe8d2f82013-10-17 08:56:076448 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276449 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076450 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276451
[email protected]1c773ea12009-04-28 19:58:426452 MockWrite data_writes[] = {
6453 MockWrite("GET / HTTP/1.1\r\n"
6454 "Host: www.google.com\r\n"
6455 "Connection: keep-alive\r\n"
6456 "Referer: http://the.previous.site.com/\r\n\r\n"),
6457 };
6458
6459 // Lastly, the server responds with the actual content.
6460 MockRead data_reads[] = {
6461 MockRead("HTTP/1.0 200 OK\r\n"),
6462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6463 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066464 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426465 };
6466
[email protected]31a2bfe2010-02-09 08:03:396467 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6468 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076469 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426470
[email protected]49639fa2011-12-20 23:22:416471 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426472
[email protected]49639fa2011-12-20 23:22:416473 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426474 EXPECT_EQ(ERR_IO_PENDING, rv);
6475
6476 rv = callback.WaitForResult();
6477 EXPECT_EQ(OK, rv);
6478}
6479
[email protected]23e482282013-06-14 16:08:026480TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426481 HttpRequestInfo request;
6482 request.method = "POST";
6483 request.url = GURL("http://www.google.com/");
6484
[email protected]3fe8d2f82013-10-17 08:56:076485 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276486 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276488
[email protected]1c773ea12009-04-28 19:58:426489 MockWrite data_writes[] = {
6490 MockWrite("POST / HTTP/1.1\r\n"
6491 "Host: www.google.com\r\n"
6492 "Connection: keep-alive\r\n"
6493 "Content-Length: 0\r\n\r\n"),
6494 };
6495
6496 // Lastly, the server responds with the actual content.
6497 MockRead data_reads[] = {
6498 MockRead("HTTP/1.0 200 OK\r\n"),
6499 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6500 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066501 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426502 };
6503
[email protected]31a2bfe2010-02-09 08:03:396504 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6505 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076506 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426507
[email protected]49639fa2011-12-20 23:22:416508 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426509
[email protected]49639fa2011-12-20 23:22:416510 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426511 EXPECT_EQ(ERR_IO_PENDING, rv);
6512
6513 rv = callback.WaitForResult();
6514 EXPECT_EQ(OK, rv);
6515}
6516
[email protected]23e482282013-06-14 16:08:026517TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426518 HttpRequestInfo request;
6519 request.method = "PUT";
6520 request.url = GURL("http://www.google.com/");
6521
[email protected]3fe8d2f82013-10-17 08:56:076522 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276523 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076524 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276525
[email protected]1c773ea12009-04-28 19:58:426526 MockWrite data_writes[] = {
6527 MockWrite("PUT / HTTP/1.1\r\n"
6528 "Host: www.google.com\r\n"
6529 "Connection: keep-alive\r\n"
6530 "Content-Length: 0\r\n\r\n"),
6531 };
6532
6533 // Lastly, the server responds with the actual content.
6534 MockRead data_reads[] = {
6535 MockRead("HTTP/1.0 200 OK\r\n"),
6536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6537 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066538 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426539 };
6540
[email protected]31a2bfe2010-02-09 08:03:396541 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6542 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076543 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426544
[email protected]49639fa2011-12-20 23:22:416545 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426546
[email protected]49639fa2011-12-20 23:22:416547 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426548 EXPECT_EQ(ERR_IO_PENDING, rv);
6549
6550 rv = callback.WaitForResult();
6551 EXPECT_EQ(OK, rv);
6552}
6553
[email protected]23e482282013-06-14 16:08:026554TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426555 HttpRequestInfo request;
6556 request.method = "HEAD";
6557 request.url = GURL("http://www.google.com/");
6558
[email protected]3fe8d2f82013-10-17 08:56:076559 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276560 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076561 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276562
[email protected]1c773ea12009-04-28 19:58:426563 MockWrite data_writes[] = {
6564 MockWrite("HEAD / HTTP/1.1\r\n"
6565 "Host: www.google.com\r\n"
6566 "Connection: keep-alive\r\n"
6567 "Content-Length: 0\r\n\r\n"),
6568 };
6569
6570 // Lastly, the server responds with the actual content.
6571 MockRead data_reads[] = {
6572 MockRead("HTTP/1.0 200 OK\r\n"),
6573 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6574 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066575 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426576 };
6577
[email protected]31a2bfe2010-02-09 08:03:396578 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6579 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076580 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426581
[email protected]49639fa2011-12-20 23:22:416582 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426583
[email protected]49639fa2011-12-20 23:22:416584 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426585 EXPECT_EQ(ERR_IO_PENDING, rv);
6586
6587 rv = callback.WaitForResult();
6588 EXPECT_EQ(OK, rv);
6589}
6590
[email protected]23e482282013-06-14 16:08:026591TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426592 HttpRequestInfo request;
6593 request.method = "GET";
6594 request.url = GURL("http://www.google.com/");
6595 request.load_flags = LOAD_BYPASS_CACHE;
6596
[email protected]3fe8d2f82013-10-17 08:56:076597 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276598 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076599 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276600
[email protected]1c773ea12009-04-28 19:58:426601 MockWrite data_writes[] = {
6602 MockWrite("GET / HTTP/1.1\r\n"
6603 "Host: www.google.com\r\n"
6604 "Connection: keep-alive\r\n"
6605 "Pragma: no-cache\r\n"
6606 "Cache-Control: no-cache\r\n\r\n"),
6607 };
6608
6609 // Lastly, the server responds with the actual content.
6610 MockRead data_reads[] = {
6611 MockRead("HTTP/1.0 200 OK\r\n"),
6612 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6613 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066614 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426615 };
6616
[email protected]31a2bfe2010-02-09 08:03:396617 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6618 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076619 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426620
[email protected]49639fa2011-12-20 23:22:416621 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426622
[email protected]49639fa2011-12-20 23:22:416623 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426624 EXPECT_EQ(ERR_IO_PENDING, rv);
6625
6626 rv = callback.WaitForResult();
6627 EXPECT_EQ(OK, rv);
6628}
6629
[email protected]23e482282013-06-14 16:08:026630TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426631 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426632 HttpRequestInfo request;
6633 request.method = "GET";
6634 request.url = GURL("http://www.google.com/");
6635 request.load_flags = LOAD_VALIDATE_CACHE;
6636
[email protected]3fe8d2f82013-10-17 08:56:076637 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276638 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276640
[email protected]1c773ea12009-04-28 19:58:426641 MockWrite data_writes[] = {
6642 MockWrite("GET / HTTP/1.1\r\n"
6643 "Host: www.google.com\r\n"
6644 "Connection: keep-alive\r\n"
6645 "Cache-Control: max-age=0\r\n\r\n"),
6646 };
6647
6648 // Lastly, the server responds with the actual content.
6649 MockRead data_reads[] = {
6650 MockRead("HTTP/1.0 200 OK\r\n"),
6651 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6652 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066653 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426654 };
6655
[email protected]31a2bfe2010-02-09 08:03:396656 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6657 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076658 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426659
[email protected]49639fa2011-12-20 23:22:416660 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426661
[email protected]49639fa2011-12-20 23:22:416662 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426663 EXPECT_EQ(ERR_IO_PENDING, rv);
6664
6665 rv = callback.WaitForResult();
6666 EXPECT_EQ(OK, rv);
6667}
6668
[email protected]23e482282013-06-14 16:08:026669TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426670 HttpRequestInfo request;
6671 request.method = "GET";
6672 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436673 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426674
[email protected]3fe8d2f82013-10-17 08:56:076675 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276676 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076677 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276678
[email protected]1c773ea12009-04-28 19:58:426679 MockWrite data_writes[] = {
6680 MockWrite("GET / HTTP/1.1\r\n"
6681 "Host: www.google.com\r\n"
6682 "Connection: keep-alive\r\n"
6683 "FooHeader: Bar\r\n\r\n"),
6684 };
6685
6686 // Lastly, the server responds with the actual content.
6687 MockRead data_reads[] = {
6688 MockRead("HTTP/1.0 200 OK\r\n"),
6689 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6690 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066691 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426692 };
6693
[email protected]31a2bfe2010-02-09 08:03:396694 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6695 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076696 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426697
[email protected]49639fa2011-12-20 23:22:416698 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426699
[email protected]49639fa2011-12-20 23:22:416700 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426701 EXPECT_EQ(ERR_IO_PENDING, rv);
6702
6703 rv = callback.WaitForResult();
6704 EXPECT_EQ(OK, rv);
6705}
6706
[email protected]23e482282013-06-14 16:08:026707TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476708 HttpRequestInfo request;
6709 request.method = "GET";
6710 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436711 request.extra_headers.SetHeader("referer", "www.foo.com");
6712 request.extra_headers.SetHeader("hEllo", "Kitty");
6713 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476714
[email protected]3fe8d2f82013-10-17 08:56:076715 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276716 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276718
[email protected]270c6412010-03-29 22:02:476719 MockWrite data_writes[] = {
6720 MockWrite("GET / HTTP/1.1\r\n"
6721 "Host: www.google.com\r\n"
6722 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166723 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476724 "hEllo: Kitty\r\n"
6725 "FoO: bar\r\n\r\n"),
6726 };
6727
6728 // Lastly, the server responds with the actual content.
6729 MockRead data_reads[] = {
6730 MockRead("HTTP/1.0 200 OK\r\n"),
6731 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6732 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066733 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476734 };
6735
6736 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6737 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:476739
[email protected]49639fa2011-12-20 23:22:416740 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:476741
[email protected]49639fa2011-12-20 23:22:416742 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:476743 EXPECT_EQ(ERR_IO_PENDING, rv);
6744
6745 rv = callback.WaitForResult();
6746 EXPECT_EQ(OK, rv);
6747}
6748
[email protected]23e482282013-06-14 16:08:026749TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276750 HttpRequestInfo request;
6751 request.method = "GET";
6752 request.url = GURL("http://www.google.com/");
6753 request.load_flags = 0;
6754
[email protected]bb88e1d32013-05-03 23:11:076755 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206756 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6757 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076758 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026759
[email protected]3fe8d2f82013-10-17 08:56:076760 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:026761 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:026763
[email protected]3cd17242009-06-23 02:59:026764 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6765 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6766
6767 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066768 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026769 MockWrite("GET / HTTP/1.1\r\n"
6770 "Host: www.google.com\r\n"
6771 "Connection: keep-alive\r\n\r\n")
6772 };
6773
6774 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066775 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:026776 MockRead("HTTP/1.0 200 OK\r\n"),
6777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6778 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066779 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026780 };
6781
[email protected]31a2bfe2010-02-09 08:03:396782 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6783 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076784 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026785
[email protected]49639fa2011-12-20 23:22:416786 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026787
[email protected]49639fa2011-12-20 23:22:416788 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026789 EXPECT_EQ(ERR_IO_PENDING, rv);
6790
6791 rv = callback.WaitForResult();
6792 EXPECT_EQ(OK, rv);
6793
6794 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506795 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026796
[email protected]029c83b62013-01-24 05:28:206797 LoadTimingInfo load_timing_info;
6798 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6799 TestLoadTimingNotReusedWithPac(load_timing_info,
6800 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6801
[email protected]3cd17242009-06-23 02:59:026802 std::string response_text;
6803 rv = ReadTransaction(trans.get(), &response_text);
6804 EXPECT_EQ(OK, rv);
6805 EXPECT_EQ("Payload", response_text);
6806}
6807
[email protected]23e482282013-06-14 16:08:026808TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276809 HttpRequestInfo request;
6810 request.method = "GET";
6811 request.url = GURL("https://www.google.com/");
6812 request.load_flags = 0;
6813
[email protected]bb88e1d32013-05-03 23:11:076814 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206815 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6816 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076817 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026818
[email protected]3fe8d2f82013-10-17 08:56:076819 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:026820 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:026822
[email protected]3cd17242009-06-23 02:59:026823 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6824 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6825
6826 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066827 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:356828 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026829 MockWrite("GET / HTTP/1.1\r\n"
6830 "Host: www.google.com\r\n"
6831 "Connection: keep-alive\r\n\r\n")
6832 };
6833
6834 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016835 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6836 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:356837 MockRead("HTTP/1.0 200 OK\r\n"),
6838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6839 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066840 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356841 };
6842
[email protected]31a2bfe2010-02-09 08:03:396843 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6844 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076845 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356846
[email protected]8ddf8322012-02-23 18:08:066847 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:356849
[email protected]49639fa2011-12-20 23:22:416850 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356851
[email protected]49639fa2011-12-20 23:22:416852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356853 EXPECT_EQ(ERR_IO_PENDING, rv);
6854
6855 rv = callback.WaitForResult();
6856 EXPECT_EQ(OK, rv);
6857
[email protected]029c83b62013-01-24 05:28:206858 LoadTimingInfo load_timing_info;
6859 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6860 TestLoadTimingNotReusedWithPac(load_timing_info,
6861 CONNECT_TIMING_HAS_SSL_TIMES);
6862
[email protected]e0c27be2009-07-15 13:09:356863 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506864 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356865
6866 std::string response_text;
6867 rv = ReadTransaction(trans.get(), &response_text);
6868 EXPECT_EQ(OK, rv);
6869 EXPECT_EQ("Payload", response_text);
6870}
6871
[email protected]23e482282013-06-14 16:08:026872TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:206873 HttpRequestInfo request;
6874 request.method = "GET";
6875 request.url = GURL("http://www.google.com/");
6876 request.load_flags = 0;
6877
[email protected]bb88e1d32013-05-03 23:11:076878 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206879 ProxyService::CreateFixed("socks4://myproxy:1080"));
6880 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076881 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:206882
[email protected]3fe8d2f82013-10-17 08:56:076883 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:206884 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:206886
6887 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6888 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6889
6890 MockWrite data_writes[] = {
6891 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6892 MockWrite("GET / HTTP/1.1\r\n"
6893 "Host: www.google.com\r\n"
6894 "Connection: keep-alive\r\n\r\n")
6895 };
6896
6897 MockRead data_reads[] = {
6898 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6899 MockRead("HTTP/1.0 200 OK\r\n"),
6900 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6901 MockRead("Payload"),
6902 MockRead(SYNCHRONOUS, OK)
6903 };
6904
6905 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6906 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076907 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:206908
6909 TestCompletionCallback callback;
6910
6911 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6912 EXPECT_EQ(ERR_IO_PENDING, rv);
6913
6914 rv = callback.WaitForResult();
6915 EXPECT_EQ(OK, rv);
6916
6917 const HttpResponseInfo* response = trans->GetResponseInfo();
6918 ASSERT_TRUE(response != NULL);
6919
6920 LoadTimingInfo load_timing_info;
6921 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6922 TestLoadTimingNotReused(load_timing_info,
6923 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6924
6925 std::string response_text;
6926 rv = ReadTransaction(trans.get(), &response_text);
6927 EXPECT_EQ(OK, rv);
6928 EXPECT_EQ("Payload", response_text);
6929}
6930
[email protected]23e482282013-06-14 16:08:026931TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276932 HttpRequestInfo request;
6933 request.method = "GET";
6934 request.url = GURL("http://www.google.com/");
6935 request.load_flags = 0;
6936
[email protected]bb88e1d32013-05-03 23:11:076937 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206938 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6939 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076940 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356941
[email protected]3fe8d2f82013-10-17 08:56:076942 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:356943 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076944 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:356945
[email protected]e0c27be2009-07-15 13:09:356946 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6947 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376948 const char kSOCKS5OkRequest[] = {
6949 0x05, // Version
6950 0x01, // Command (CONNECT)
6951 0x00, // Reserved.
6952 0x03, // Address type (DOMAINNAME).
6953 0x0E, // Length of domain (14)
6954 // Domain string:
6955 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6956 0x00, 0x50, // 16-bit port (80)
6957 };
[email protected]e0c27be2009-07-15 13:09:356958 const char kSOCKS5OkResponse[] =
6959 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
6960
6961 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066962 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6963 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:356964 MockWrite("GET / HTTP/1.1\r\n"
6965 "Host: www.google.com\r\n"
6966 "Connection: keep-alive\r\n\r\n")
6967 };
6968
6969 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016970 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6971 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:356972 MockRead("HTTP/1.0 200 OK\r\n"),
6973 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6974 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066975 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356976 };
6977
[email protected]31a2bfe2010-02-09 08:03:396978 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6979 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076980 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356981
[email protected]49639fa2011-12-20 23:22:416982 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356983
[email protected]49639fa2011-12-20 23:22:416984 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356985 EXPECT_EQ(ERR_IO_PENDING, rv);
6986
6987 rv = callback.WaitForResult();
6988 EXPECT_EQ(OK, rv);
6989
6990 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506991 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356992
[email protected]029c83b62013-01-24 05:28:206993 LoadTimingInfo load_timing_info;
6994 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6995 TestLoadTimingNotReusedWithPac(load_timing_info,
6996 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6997
[email protected]e0c27be2009-07-15 13:09:356998 std::string response_text;
6999 rv = ReadTransaction(trans.get(), &response_text);
7000 EXPECT_EQ(OK, rv);
7001 EXPECT_EQ("Payload", response_text);
7002}
7003
[email protected]23e482282013-06-14 16:08:027004TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277005 HttpRequestInfo request;
7006 request.method = "GET";
7007 request.url = GURL("https://www.google.com/");
7008 request.load_flags = 0;
7009
[email protected]bb88e1d32013-05-03 23:11:077010 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207011 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7012 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077013 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357014
[email protected]3fe8d2f82013-10-17 08:56:077015 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357016 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357018
[email protected]e0c27be2009-07-15 13:09:357019 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7020 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377021 const unsigned char kSOCKS5OkRequest[] = {
7022 0x05, // Version
7023 0x01, // Command (CONNECT)
7024 0x00, // Reserved.
7025 0x03, // Address type (DOMAINNAME).
7026 0x0E, // Length of domain (14)
7027 // Domain string:
7028 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7029 0x01, 0xBB, // 16-bit port (443)
7030 };
7031
[email protected]e0c27be2009-07-15 13:09:357032 const char kSOCKS5OkResponse[] =
7033 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7034
7035 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067036 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7037 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357038 arraysize(kSOCKS5OkRequest)),
7039 MockWrite("GET / HTTP/1.1\r\n"
7040 "Host: www.google.com\r\n"
7041 "Connection: keep-alive\r\n\r\n")
7042 };
7043
7044 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017045 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7046 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027047 MockRead("HTTP/1.0 200 OK\r\n"),
7048 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7049 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067050 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027051 };
7052
[email protected]31a2bfe2010-02-09 08:03:397053 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7054 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077055 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027056
[email protected]8ddf8322012-02-23 18:08:067057 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027059
[email protected]49639fa2011-12-20 23:22:417060 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027061
[email protected]49639fa2011-12-20 23:22:417062 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027063 EXPECT_EQ(ERR_IO_PENDING, rv);
7064
7065 rv = callback.WaitForResult();
7066 EXPECT_EQ(OK, rv);
7067
7068 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507069 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027070
[email protected]029c83b62013-01-24 05:28:207071 LoadTimingInfo load_timing_info;
7072 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7073 TestLoadTimingNotReusedWithPac(load_timing_info,
7074 CONNECT_TIMING_HAS_SSL_TIMES);
7075
[email protected]3cd17242009-06-23 02:59:027076 std::string response_text;
7077 rv = ReadTransaction(trans.get(), &response_text);
7078 EXPECT_EQ(OK, rv);
7079 EXPECT_EQ("Payload", response_text);
7080}
7081
[email protected]448d4ca52012-03-04 04:12:237082namespace {
7083
[email protected]04e5be32009-06-26 20:00:317084// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067085
7086struct GroupNameTest {
7087 std::string proxy_server;
7088 std::string url;
7089 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187090 bool ssl;
[email protected]2d731a32010-04-29 01:04:067091};
7092
7093scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437094 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077095 SpdySessionDependencies* session_deps_) {
7096 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067097
[email protected]30d4c022013-07-18 22:58:167098 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537099 session->http_server_properties();
7100 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067101 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437102 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067103
7104 return session;
7105}
7106
7107int GroupNameTransactionHelper(
7108 const std::string& url,
7109 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067110 HttpRequestInfo request;
7111 request.method = "GET";
7112 request.url = GURL(url);
7113 request.load_flags = 0;
7114
[email protected]262eec82013-03-19 21:01:367115 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277117
[email protected]49639fa2011-12-20 23:22:417118 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067119
7120 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417121 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067122}
7123
[email protected]448d4ca52012-03-04 04:12:237124} // namespace
7125
[email protected]23e482282013-06-14 16:08:027126TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067127 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317128 {
[email protected]2d731a32010-04-29 01:04:067129 "", // unused
[email protected]04e5be32009-06-26 20:00:317130 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547131 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187132 false,
[email protected]2ff8b312010-04-26 22:20:547133 },
7134 {
[email protected]2d731a32010-04-29 01:04:067135 "", // unused
[email protected]2ff8b312010-04-26 22:20:547136 "http://[2001:1418:13:1::25]/direct",
7137 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187138 false,
[email protected]04e5be32009-06-26 20:00:317139 },
[email protected]04e5be32009-06-26 20:00:317140
7141 // SSL Tests
7142 {
[email protected]2d731a32010-04-29 01:04:067143 "", // unused
[email protected]04e5be32009-06-26 20:00:317144 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027145 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187146 true,
[email protected]04e5be32009-06-26 20:00:317147 },
7148 {
[email protected]2d731a32010-04-29 01:04:067149 "", // unused
7150 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027151 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187152 true,
[email protected]04e5be32009-06-26 20:00:317153 },
7154 {
[email protected]2d731a32010-04-29 01:04:067155 "", // unused
[email protected]2ff8b312010-04-26 22:20:547156 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027157 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187158 true,
[email protected]2ff8b312010-04-26 22:20:547159 },
[email protected]2d731a32010-04-29 01:04:067160 };
[email protected]2ff8b312010-04-26 22:20:547161
[email protected]8e6441ca2010-08-19 05:56:387162 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067163
7164 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077165 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027166 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067167 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437168 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067169
7170 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287171 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7172 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137173 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347174 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447175 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7176 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027177 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7178 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447179 peer.SetClientSocketPoolManager(
7180 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067181
7182 EXPECT_EQ(ERR_IO_PENDING,
7183 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187184 if (tests[i].ssl)
7185 EXPECT_EQ(tests[i].expected_group_name,
7186 ssl_conn_pool->last_group_name_received());
7187 else
7188 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287189 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067190 }
7191
[email protected]2d731a32010-04-29 01:04:067192}
7193
[email protected]23e482282013-06-14 16:08:027194TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067195 const GroupNameTest tests[] = {
7196 {
7197 "http_proxy",
7198 "http://www.google.com/http_proxy_normal",
7199 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187200 false,
[email protected]2d731a32010-04-29 01:04:067201 },
7202
7203 // SSL Tests
7204 {
7205 "http_proxy",
7206 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027207 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187208 true,
[email protected]2d731a32010-04-29 01:04:067209 },
[email protected]af3490e2010-10-16 21:02:297210
[email protected]9faeded92010-04-29 20:03:057211 {
7212 "http_proxy",
7213 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027214 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187215 true,
[email protected]9faeded92010-04-29 20:03:057216 },
[email protected]45499252013-01-23 17:12:567217
7218 {
7219 "http_proxy",
7220 "ftp://ftp.google.com/http_proxy_normal",
7221 "ftp/ftp.google.com:21",
7222 false,
7223 },
[email protected]2d731a32010-04-29 01:04:067224 };
7225
[email protected]8e6441ca2010-08-19 05:56:387226 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067227
7228 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077229 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027230 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067231 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437232 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067233
7234 HttpNetworkSessionPeer peer(session);
7235
[email protected]e60e47a2010-07-14 03:37:187236 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137237 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347238 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137239 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347240 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027241
[email protected]831e4a32013-11-14 02:14:447242 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7243 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027244 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7245 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447246 peer.SetClientSocketPoolManager(
7247 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067248
7249 EXPECT_EQ(ERR_IO_PENDING,
7250 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187251 if (tests[i].ssl)
7252 EXPECT_EQ(tests[i].expected_group_name,
7253 ssl_conn_pool->last_group_name_received());
7254 else
7255 EXPECT_EQ(tests[i].expected_group_name,
7256 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067257 }
[email protected]2d731a32010-04-29 01:04:067258}
7259
[email protected]23e482282013-06-14 16:08:027260TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067261 const GroupNameTest tests[] = {
7262 {
7263 "socks4://socks_proxy:1080",
7264 "http://www.google.com/socks4_direct",
7265 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187266 false,
[email protected]2d731a32010-04-29 01:04:067267 },
7268 {
7269 "socks5://socks_proxy:1080",
7270 "http://www.google.com/socks5_direct",
7271 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187272 false,
[email protected]2d731a32010-04-29 01:04:067273 },
7274
7275 // SSL Tests
7276 {
7277 "socks4://socks_proxy:1080",
7278 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027279 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187280 true,
[email protected]2d731a32010-04-29 01:04:067281 },
7282 {
7283 "socks5://socks_proxy:1080",
7284 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027285 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187286 true,
[email protected]2d731a32010-04-29 01:04:067287 },
[email protected]af3490e2010-10-16 21:02:297288
[email protected]9faeded92010-04-29 20:03:057289 {
7290 "socks4://socks_proxy:1080",
7291 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027292 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187293 true,
[email protected]9faeded92010-04-29 20:03:057294 },
[email protected]04e5be32009-06-26 20:00:317295 };
7296
[email protected]8e6441ca2010-08-19 05:56:387297 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547298
[email protected]04e5be32009-06-26 20:00:317299 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077300 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027301 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067302 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437303 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027304
[email protected]2d731a32010-04-29 01:04:067305 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317306
[email protected]e60e47a2010-07-14 03:37:187307 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137308 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347309 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137310 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347311 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027312
[email protected]831e4a32013-11-14 02:14:447313 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7314 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027315 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7316 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447317 peer.SetClientSocketPoolManager(
7318 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317319
[email protected]262eec82013-03-19 21:01:367320 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507321 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317322
[email protected]2d731a32010-04-29 01:04:067323 EXPECT_EQ(ERR_IO_PENDING,
7324 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187325 if (tests[i].ssl)
7326 EXPECT_EQ(tests[i].expected_group_name,
7327 ssl_conn_pool->last_group_name_received());
7328 else
7329 EXPECT_EQ(tests[i].expected_group_name,
7330 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317331 }
7332}
7333
[email protected]23e482282013-06-14 16:08:027334TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277335 HttpRequestInfo request;
7336 request.method = "GET";
7337 request.url = GURL("http://www.google.com/");
7338
[email protected]bb88e1d32013-05-03 23:11:077339 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007340 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327341
[email protected]69719062010-01-05 20:09:217342 // This simulates failure resolving all hostnames; that means we will fail
7343 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077344 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327345
[email protected]3fe8d2f82013-10-17 08:56:077346 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257347 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257349
[email protected]49639fa2011-12-20 23:22:417350 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257351
[email protected]49639fa2011-12-20 23:22:417352 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257353 EXPECT_EQ(ERR_IO_PENDING, rv);
7354
[email protected]9172a982009-06-06 00:30:257355 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017356 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257357}
7358
[email protected]685af592010-05-11 19:31:247359// Base test to make sure that when the load flags for a request specify to
7360// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027361void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077362 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277363 // Issue a request, asking to bypass the cache(s).
7364 HttpRequestInfo request;
7365 request.method = "GET";
7366 request.load_flags = load_flags;
7367 request.url = GURL("http://www.google.com/");
7368
[email protected]a2c2fb92009-07-18 07:31:047369 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077370 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327371
[email protected]3fe8d2f82013-10-17 08:56:077372 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7373 scoped_ptr<HttpTransaction> trans(
7374 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287375
[email protected]6e78dfb2011-07-28 21:34:477376 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287377 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297378 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077379 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107380 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7381 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417382 &addrlist,
7383 callback.callback(),
7384 NULL,
7385 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477386 EXPECT_EQ(ERR_IO_PENDING, rv);
7387 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287388 EXPECT_EQ(OK, rv);
7389
7390 // Verify that it was added to host cache, by doing a subsequent async lookup
7391 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077392 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107393 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7394 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417395 &addrlist,
7396 callback.callback(),
7397 NULL,
7398 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327399 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287400
7401 // Inject a failure the next time that "www.google.com" is resolved. This way
7402 // we can tell if the next lookup hit the cache, or the "network".
7403 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077404 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287405
7406 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7407 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067408 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397409 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077410 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287411
[email protected]3b9cca42009-06-16 01:08:287412 // Run the request.
[email protected]49639fa2011-12-20 23:22:417413 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287414 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417415 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287416
7417 // If we bypassed the cache, we would have gotten a failure while resolving
7418 // "www.google.com".
7419 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7420}
7421
[email protected]685af592010-05-11 19:31:247422// There are multiple load flags that should trigger the host cache bypass.
7423// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027424TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247425 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7426}
7427
[email protected]23e482282013-06-14 16:08:027428TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247429 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7430}
7431
[email protected]23e482282013-06-14 16:08:027432TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247433 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7434}
7435
[email protected]0877e3d2009-10-17 22:29:577436// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027437TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577438 HttpRequestInfo request;
7439 request.method = "GET";
7440 request.url = GURL("http://www.foo.com/");
7441 request.load_flags = 0;
7442
7443 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067444 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577445 };
[email protected]31a2bfe2010-02-09 08:03:397446 StaticSocketDataProvider data(NULL, 0,
7447 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077448 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077449 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577450
[email protected]49639fa2011-12-20 23:22:417451 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577452
7453 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577455
[email protected]49639fa2011-12-20 23:22:417456 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577457 EXPECT_EQ(ERR_IO_PENDING, rv);
7458
7459 rv = callback.WaitForResult();
7460 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7461}
7462
7463// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027464TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577465 HttpRequestInfo request;
7466 request.method = "GET";
7467 request.url = GURL("http://www.foo.com/");
7468 request.load_flags = 0;
7469
7470 MockRead data_reads[] = {
7471 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067472 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577473 };
7474
[email protected]31a2bfe2010-02-09 08:03:397475 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077476 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077477 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577478
[email protected]49639fa2011-12-20 23:22:417479 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577480
7481 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077482 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577483
[email protected]49639fa2011-12-20 23:22:417484 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577485 EXPECT_EQ(ERR_IO_PENDING, rv);
7486
7487 rv = callback.WaitForResult();
7488 EXPECT_EQ(OK, rv);
7489
7490 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507491 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577492
[email protected]90499482013-06-01 00:39:507493 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577494 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7495
7496 std::string response_data;
7497 rv = ReadTransaction(trans.get(), &response_data);
7498 EXPECT_EQ(OK, rv);
7499 EXPECT_EQ("", response_data);
7500}
7501
7502// Make sure that a dropped connection while draining the body for auth
7503// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027504TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577505 HttpRequestInfo request;
7506 request.method = "GET";
7507 request.url = GURL("http://www.google.com/");
7508 request.load_flags = 0;
7509
7510 MockWrite data_writes1[] = {
7511 MockWrite("GET / HTTP/1.1\r\n"
7512 "Host: www.google.com\r\n"
7513 "Connection: keep-alive\r\n\r\n"),
7514 };
7515
7516 MockRead data_reads1[] = {
7517 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7518 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7519 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7520 MockRead("Content-Length: 14\r\n\r\n"),
7521 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067522 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577523 };
7524
[email protected]31a2bfe2010-02-09 08:03:397525 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7526 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577528
7529 // After calling trans->RestartWithAuth(), this is the request we should
7530 // be issuing -- the final header line contains the credentials.
7531 MockWrite data_writes2[] = {
7532 MockWrite("GET / HTTP/1.1\r\n"
7533 "Host: www.google.com\r\n"
7534 "Connection: keep-alive\r\n"
7535 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7536 };
7537
7538 // Lastly, the server responds with the actual content.
7539 MockRead data_reads2[] = {
7540 MockRead("HTTP/1.1 200 OK\r\n"),
7541 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7542 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067543 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577544 };
7545
[email protected]31a2bfe2010-02-09 08:03:397546 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7547 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077548 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077549 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577550
[email protected]49639fa2011-12-20 23:22:417551 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577552
[email protected]262eec82013-03-19 21:01:367553 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507554 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507555
[email protected]49639fa2011-12-20 23:22:417556 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577557 EXPECT_EQ(ERR_IO_PENDING, rv);
7558
7559 rv = callback1.WaitForResult();
7560 EXPECT_EQ(OK, rv);
7561
7562 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507563 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047564 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577565
[email protected]49639fa2011-12-20 23:22:417566 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577567
[email protected]49639fa2011-12-20 23:22:417568 rv = trans->RestartWithAuth(
7569 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577570 EXPECT_EQ(ERR_IO_PENDING, rv);
7571
7572 rv = callback2.WaitForResult();
7573 EXPECT_EQ(OK, rv);
7574
7575 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507576 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577577 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7578 EXPECT_EQ(100, response->headers->GetContentLength());
7579}
7580
7581// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027582TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077583 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577584
7585 HttpRequestInfo request;
7586 request.method = "GET";
7587 request.url = GURL("https://www.google.com/");
7588 request.load_flags = 0;
7589
7590 MockRead proxy_reads[] = {
7591 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067592 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577593 };
7594
[email protected]31a2bfe2010-02-09 08:03:397595 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067596 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577597
[email protected]bb88e1d32013-05-03 23:11:077598 session_deps_.socket_factory->AddSocketDataProvider(&data);
7599 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577600
[email protected]49639fa2011-12-20 23:22:417601 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577602
[email protected]bb88e1d32013-05-03 23:11:077603 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577604
[email protected]3fe8d2f82013-10-17 08:56:077605 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577606 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577608
[email protected]49639fa2011-12-20 23:22:417609 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577610 EXPECT_EQ(ERR_IO_PENDING, rv);
7611
7612 rv = callback.WaitForResult();
7613 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7614}
7615
[email protected]23e482282013-06-14 16:08:027616TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467617 HttpRequestInfo request;
7618 request.method = "GET";
7619 request.url = GURL("http://www.google.com/");
7620 request.load_flags = 0;
7621
[email protected]3fe8d2f82013-10-17 08:56:077622 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277623 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077624 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277625
[email protected]e22e1362009-11-23 21:31:127626 MockRead data_reads[] = {
7627 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067628 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127629 };
[email protected]9492e4a2010-02-24 00:58:467630
7631 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077632 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467633
[email protected]49639fa2011-12-20 23:22:417634 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467635
[email protected]49639fa2011-12-20 23:22:417636 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467637 EXPECT_EQ(ERR_IO_PENDING, rv);
7638
7639 EXPECT_EQ(OK, callback.WaitForResult());
7640
7641 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507642 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467643
[email protected]90499482013-06-01 00:39:507644 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467645 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7646
7647 std::string response_data;
7648 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237649 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127650}
7651
[email protected]23e482282013-06-14 16:08:027652TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157653 base::FilePath temp_file_path;
[email protected]95d88ffe2010-02-04 21:25:337654 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
7655 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217656 UploadFileElementReader::ScopedOverridingContentLengthForTests
7657 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337658
[email protected]b2d26cfd2012-12-11 10:36:067659 ScopedVector<UploadElementReader> element_readers;
7660 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367661 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7662 temp_file_path,
7663 0,
7664 kuint64max,
7665 base::Time()));
[email protected]96c77a72013-09-24 09:49:207666 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277667
7668 HttpRequestInfo request;
7669 request.method = "POST";
7670 request.url = GURL("http://www.google.com/upload");
7671 request.upload_data_stream = &upload_data_stream;
7672 request.load_flags = 0;
7673
[email protected]3fe8d2f82013-10-17 08:56:077674 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277675 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077676 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:337677
7678 MockRead data_reads[] = {
7679 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7680 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067681 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337682 };
[email protected]31a2bfe2010-02-09 08:03:397683 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077684 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337685
[email protected]49639fa2011-12-20 23:22:417686 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337687
[email protected]49639fa2011-12-20 23:22:417688 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337689 EXPECT_EQ(ERR_IO_PENDING, rv);
7690
7691 rv = callback.WaitForResult();
7692 EXPECT_EQ(OK, rv);
7693
7694 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507695 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337696
[email protected]90499482013-06-01 00:39:507697 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337698 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7699
7700 std::string response_data;
7701 rv = ReadTransaction(trans.get(), &response_data);
7702 EXPECT_EQ(OK, rv);
7703 EXPECT_EQ("hello world", response_data);
7704
[email protected]dd3aa792013-07-16 19:10:237705 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:337706}
7707
[email protected]23e482282013-06-14 16:08:027708TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157709 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367710 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7711 std::string temp_file_content("Unreadable file.");
7712 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
7713 temp_file_content.length()));
7714 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7715
[email protected]b2d26cfd2012-12-11 10:36:067716 ScopedVector<UploadElementReader> element_readers;
7717 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367718 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7719 temp_file,
7720 0,
7721 kuint64max,
7722 base::Time()));
[email protected]96c77a72013-09-24 09:49:207723 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277724
7725 HttpRequestInfo request;
7726 request.method = "POST";
7727 request.url = GURL("http://www.google.com/upload");
7728 request.upload_data_stream = &upload_data_stream;
7729 request.load_flags = 0;
7730
[email protected]999dd8c2013-11-12 06:45:547731 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:077732 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277733 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:367735
[email protected]999dd8c2013-11-12 06:45:547736 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077737 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367738
[email protected]49639fa2011-12-20 23:22:417739 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:367740
[email protected]49639fa2011-12-20 23:22:417741 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367742 EXPECT_EQ(ERR_IO_PENDING, rv);
7743
7744 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:547745 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:367746
7747 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:547748 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:367749
[email protected]dd3aa792013-07-16 19:10:237750 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367751}
7752
[email protected]02cad5d2013-10-02 08:14:037753TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
7754 class FakeUploadElementReader : public UploadElementReader {
7755 public:
7756 FakeUploadElementReader() {}
7757 virtual ~FakeUploadElementReader() {}
7758
7759 const CompletionCallback& callback() const { return callback_; }
7760
7761 // UploadElementReader overrides:
7762 virtual int Init(const CompletionCallback& callback) OVERRIDE {
7763 callback_ = callback;
7764 return ERR_IO_PENDING;
7765 }
7766 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
7767 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
7768 virtual int Read(IOBuffer* buf,
7769 int buf_length,
7770 const CompletionCallback& callback) OVERRIDE {
7771 return ERR_FAILED;
7772 }
7773
7774 private:
7775 CompletionCallback callback_;
7776 };
7777
7778 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
7779 ScopedVector<UploadElementReader> element_readers;
7780 element_readers.push_back(fake_reader);
7781 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7782
7783 HttpRequestInfo request;
7784 request.method = "POST";
7785 request.url = GURL("http://www.google.com/upload");
7786 request.upload_data_stream = &upload_data_stream;
7787 request.load_flags = 0;
7788
[email protected]3fe8d2f82013-10-17 08:56:077789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:037790 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:037792
7793 StaticSocketDataProvider data;
7794 session_deps_.socket_factory->AddSocketDataProvider(&data);
7795
7796 TestCompletionCallback callback;
7797 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7798 EXPECT_EQ(ERR_IO_PENDING, rv);
7799 base::MessageLoop::current()->RunUntilIdle();
7800
7801 // Transaction is pending on request body initialization.
7802 ASSERT_FALSE(fake_reader->callback().is_null());
7803
7804 // Return Init()'s result after the transaction gets destroyed.
7805 trans.reset();
7806 fake_reader->callback().Run(OK); // Should not crash.
7807}
7808
[email protected]aeefc9e82010-02-19 16:18:277809// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:027810TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:277811
7812 HttpRequestInfo request;
7813 request.method = "GET";
7814 request.url = GURL("http://www.google.com/");
7815 request.load_flags = 0;
7816
7817 // First transaction will request a resource and receive a Basic challenge
7818 // with realm="first_realm".
7819 MockWrite data_writes1[] = {
7820 MockWrite("GET / HTTP/1.1\r\n"
7821 "Host: www.google.com\r\n"
7822 "Connection: keep-alive\r\n"
7823 "\r\n"),
7824 };
7825 MockRead data_reads1[] = {
7826 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7827 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7828 "\r\n"),
7829 };
7830
7831 // After calling trans->RestartWithAuth(), provide an Authentication header
7832 // for first_realm. The server will reject and provide a challenge with
7833 // second_realm.
7834 MockWrite data_writes2[] = {
7835 MockWrite("GET / HTTP/1.1\r\n"
7836 "Host: www.google.com\r\n"
7837 "Connection: keep-alive\r\n"
7838 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7839 "\r\n"),
7840 };
7841 MockRead data_reads2[] = {
7842 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7843 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7844 "\r\n"),
7845 };
7846
7847 // This again fails, and goes back to first_realm. Make sure that the
7848 // entry is removed from cache.
7849 MockWrite data_writes3[] = {
7850 MockWrite("GET / HTTP/1.1\r\n"
7851 "Host: www.google.com\r\n"
7852 "Connection: keep-alive\r\n"
7853 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
7854 "\r\n"),
7855 };
7856 MockRead data_reads3[] = {
7857 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7858 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7859 "\r\n"),
7860 };
7861
7862 // Try one last time (with the correct password) and get the resource.
7863 MockWrite data_writes4[] = {
7864 MockWrite("GET / HTTP/1.1\r\n"
7865 "Host: www.google.com\r\n"
7866 "Connection: keep-alive\r\n"
7867 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
7868 "\r\n"),
7869 };
7870 MockRead data_reads4[] = {
7871 MockRead("HTTP/1.1 200 OK\r\n"
7872 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:507873 "Content-Length: 5\r\n"
7874 "\r\n"
7875 "hello"),
[email protected]aeefc9e82010-02-19 16:18:277876 };
7877
7878 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7879 data_writes1, arraysize(data_writes1));
7880 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7881 data_writes2, arraysize(data_writes2));
7882 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7883 data_writes3, arraysize(data_writes3));
7884 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
7885 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:077886 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7887 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7888 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7889 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:277890
[email protected]49639fa2011-12-20 23:22:417891 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:277892
[email protected]3fe8d2f82013-10-17 08:56:077893 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:507894 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:507896
[email protected]aeefc9e82010-02-19 16:18:277897 // Issue the first request with Authorize headers. There should be a
7898 // password prompt for first_realm waiting to be filled in after the
7899 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417900 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:277901 EXPECT_EQ(ERR_IO_PENDING, rv);
7902 rv = callback1.WaitForResult();
7903 EXPECT_EQ(OK, rv);
7904 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507905 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047906 const AuthChallengeInfo* challenge = response->auth_challenge.get();
7907 ASSERT_FALSE(challenge == NULL);
7908 EXPECT_FALSE(challenge->is_proxy);
7909 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7910 EXPECT_EQ("first_realm", challenge->realm);
7911 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277912
7913 // Issue the second request with an incorrect password. There should be a
7914 // password prompt for second_realm waiting to be filled in after the
7915 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417916 TestCompletionCallback callback2;
7917 rv = trans->RestartWithAuth(
7918 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:277919 EXPECT_EQ(ERR_IO_PENDING, rv);
7920 rv = callback2.WaitForResult();
7921 EXPECT_EQ(OK, rv);
7922 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507923 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047924 challenge = response->auth_challenge.get();
7925 ASSERT_FALSE(challenge == NULL);
7926 EXPECT_FALSE(challenge->is_proxy);
7927 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7928 EXPECT_EQ("second_realm", challenge->realm);
7929 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277930
7931 // Issue the third request with another incorrect password. There should be
7932 // a password prompt for first_realm waiting to be filled in. If the password
7933 // prompt is not present, it indicates that the HttpAuthCacheEntry for
7934 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:417935 TestCompletionCallback callback3;
7936 rv = trans->RestartWithAuth(
7937 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:277938 EXPECT_EQ(ERR_IO_PENDING, rv);
7939 rv = callback3.WaitForResult();
7940 EXPECT_EQ(OK, rv);
7941 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507942 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047943 challenge = response->auth_challenge.get();
7944 ASSERT_FALSE(challenge == NULL);
7945 EXPECT_FALSE(challenge->is_proxy);
7946 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7947 EXPECT_EQ("first_realm", challenge->realm);
7948 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277949
7950 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:417951 TestCompletionCallback callback4;
7952 rv = trans->RestartWithAuth(
7953 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:277954 EXPECT_EQ(ERR_IO_PENDING, rv);
7955 rv = callback4.WaitForResult();
7956 EXPECT_EQ(OK, rv);
7957 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507958 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:277959 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7960}
7961
[email protected]23e482282013-06-14 16:08:027962TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:037963 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:237964 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:427965
[email protected]8a0fc822013-06-27 20:52:437966 std::string alternate_protocol_http_header =
7967 GetAlternateProtocolHttpHeader();
7968
[email protected]564b4912010-03-09 16:30:427969 MockRead data_reads[] = {
7970 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:437971 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:427972 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067973 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:427974 };
7975
7976 HttpRequestInfo request;
7977 request.method = "GET";
7978 request.url = GURL("http://www.google.com/");
7979 request.load_flags = 0;
7980
7981 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7982
[email protected]bb88e1d32013-05-03 23:11:077983 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:427984
[email protected]49639fa2011-12-20 23:22:417985 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:427986
[email protected]bb88e1d32013-05-03 23:11:077987 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:367988 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507989 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:427990
[email protected]49639fa2011-12-20 23:22:417991 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:427992 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:537993
[email protected]2fbaecf22010-07-22 22:20:357994 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]17291a022011-10-10 07:32:537995 const HttpServerProperties& http_server_properties =
7996 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:427997 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:537998 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:427999
8000 EXPECT_EQ(OK, callback.WaitForResult());
8001
8002 const HttpResponseInfo* response = trans->GetResponseInfo();
8003 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508004 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428005 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538006 EXPECT_FALSE(response->was_fetched_via_spdy);
8007 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428008
8009 std::string response_data;
8010 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8011 EXPECT_EQ("hello world", response_data);
8012
[email protected]17291a022011-10-10 07:32:538013 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8014 const PortAlternateProtocolPair alternate =
8015 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8016 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428017 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438018 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428019 EXPECT_TRUE(expected_alternate.Equals(alternate));
8020}
8021
[email protected]23e482282013-06-14 16:08:028022TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238023 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388024 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428025
8026 HttpRequestInfo request;
8027 request.method = "GET";
8028 request.url = GURL("http://www.google.com/");
8029 request.load_flags = 0;
8030
[email protected]d973e99a2012-02-17 21:02:368031 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428032 StaticSocketDataProvider first_data;
8033 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078034 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428035
8036 MockRead data_reads[] = {
8037 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8038 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068039 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428040 };
8041 StaticSocketDataProvider second_data(
8042 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078043 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428044
[email protected]bb88e1d32013-05-03 23:11:078045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428046
[email protected]30d4c022013-07-18 22:58:168047 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538048 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118049 // Port must be < 1024, or the header will be ignored (since initial port was
8050 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538051 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118052 HostPortPair::FromURL(request.url),
8053 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438054 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428055
[email protected]262eec82013-03-19 21:01:368056 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508057 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418058 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428059
[email protected]49639fa2011-12-20 23:22:418060 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428061 EXPECT_EQ(ERR_IO_PENDING, rv);
8062 EXPECT_EQ(OK, callback.WaitForResult());
8063
8064 const HttpResponseInfo* response = trans->GetResponseInfo();
8065 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508066 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428067 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8068
8069 std::string response_data;
8070 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8071 EXPECT_EQ("hello world", response_data);
8072
[email protected]17291a022011-10-10 07:32:538073 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118074 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538075 const PortAlternateProtocolPair alternate =
8076 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118077 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538078 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428079}
8080
[email protected]23e482282013-06-14 16:08:028081TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238082 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118083 // Ensure that we're not allowed to redirect traffic via an alternate
8084 // protocol to an unrestricted (port >= 1024) when the original traffic was
8085 // on a restricted port (port < 1024). Ensure that we can redirect in all
8086 // other cases.
8087 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118088
8089 HttpRequestInfo restricted_port_request;
8090 restricted_port_request.method = "GET";
8091 restricted_port_request.url = GURL("http://www.google.com:1023/");
8092 restricted_port_request.load_flags = 0;
8093
[email protected]d973e99a2012-02-17 21:02:368094 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118095 StaticSocketDataProvider first_data;
8096 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078097 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118098
8099 MockRead data_reads[] = {
8100 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8101 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068102 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118103 };
8104 StaticSocketDataProvider second_data(
8105 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078106 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118107
[email protected]bb88e1d32013-05-03 23:11:078108 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118109
[email protected]30d4c022013-07-18 22:58:168110 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538111 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118112 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538113 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118114 HostPortPair::FromURL(restricted_port_request.url),
8115 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438116 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118117
[email protected]262eec82013-03-19 21:01:368118 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418120 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118121
[email protected]49639fa2011-12-20 23:22:418122 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368123 &restricted_port_request,
8124 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118125 EXPECT_EQ(ERR_IO_PENDING, rv);
8126 // Invalid change to unrestricted port should fail.
8127 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198128}
[email protected]3912662a32011-10-04 00:51:118129
[email protected]23e482282013-06-14 16:08:028130TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198131 AlternateProtocolPortRestrictedPermitted) {
8132 // Ensure that we're allowed to redirect traffic via an alternate
8133 // protocol to an unrestricted (port >= 1024) when the original traffic was
8134 // on a restricted port (port < 1024) if we set
8135 // enable_user_alternate_protocol_ports.
8136
8137 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078138 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198139
8140 HttpRequestInfo restricted_port_request;
8141 restricted_port_request.method = "GET";
8142 restricted_port_request.url = GURL("http://www.google.com:1023/");
8143 restricted_port_request.load_flags = 0;
8144
8145 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8146 StaticSocketDataProvider first_data;
8147 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078148 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198149
8150 MockRead data_reads[] = {
8151 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8152 MockRead("hello world"),
8153 MockRead(ASYNC, OK),
8154 };
8155 StaticSocketDataProvider second_data(
8156 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078157 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198158
[email protected]bb88e1d32013-05-03 23:11:078159 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198160
[email protected]30d4c022013-07-18 22:58:168161 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198162 session->http_server_properties();
8163 const int kUnrestrictedAlternatePort = 1024;
8164 http_server_properties->SetAlternateProtocol(
8165 HostPortPair::FromURL(restricted_port_request.url),
8166 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438167 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198168
[email protected]262eec82013-03-19 21:01:368169 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508170 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198171 TestCompletionCallback callback;
8172
8173 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368174 &restricted_port_request,
8175 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198176 // Change to unrestricted port should succeed.
8177 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118178}
8179
[email protected]23e482282013-06-14 16:08:028180TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238181 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118182 // Ensure that we're not allowed to redirect traffic via an alternate
8183 // protocol to an unrestricted (port >= 1024) when the original traffic was
8184 // on a restricted port (port < 1024). Ensure that we can redirect in all
8185 // other cases.
8186 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118187
8188 HttpRequestInfo restricted_port_request;
8189 restricted_port_request.method = "GET";
8190 restricted_port_request.url = GURL("http://www.google.com:1023/");
8191 restricted_port_request.load_flags = 0;
8192
[email protected]d973e99a2012-02-17 21:02:368193 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118194 StaticSocketDataProvider first_data;
8195 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078196 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118197
8198 MockRead data_reads[] = {
8199 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8200 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068201 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118202 };
8203 StaticSocketDataProvider second_data(
8204 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078205 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118206
[email protected]bb88e1d32013-05-03 23:11:078207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118208
[email protected]30d4c022013-07-18 22:58:168209 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538210 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118211 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538212 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118213 HostPortPair::FromURL(restricted_port_request.url),
8214 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438215 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118216
[email protected]262eec82013-03-19 21:01:368217 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418219 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118220
[email protected]49639fa2011-12-20 23:22:418221 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368222 &restricted_port_request,
8223 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118224 EXPECT_EQ(ERR_IO_PENDING, rv);
8225 // Valid change to restricted port should pass.
8226 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118227}
8228
[email protected]23e482282013-06-14 16:08:028229TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238230 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118231 // Ensure that we're not allowed to redirect traffic via an alternate
8232 // protocol to an unrestricted (port >= 1024) when the original traffic was
8233 // on a restricted port (port < 1024). Ensure that we can redirect in all
8234 // other cases.
8235 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118236
8237 HttpRequestInfo unrestricted_port_request;
8238 unrestricted_port_request.method = "GET";
8239 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8240 unrestricted_port_request.load_flags = 0;
8241
[email protected]d973e99a2012-02-17 21:02:368242 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118243 StaticSocketDataProvider first_data;
8244 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078245 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118246
8247 MockRead data_reads[] = {
8248 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8249 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068250 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118251 };
8252 StaticSocketDataProvider second_data(
8253 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078254 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118255
[email protected]bb88e1d32013-05-03 23:11:078256 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118257
[email protected]30d4c022013-07-18 22:58:168258 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538259 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118260 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538261 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118262 HostPortPair::FromURL(unrestricted_port_request.url),
8263 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438264 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118265
[email protected]262eec82013-03-19 21:01:368266 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418268 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118269
[email protected]49639fa2011-12-20 23:22:418270 int rv = trans->Start(
8271 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118272 EXPECT_EQ(ERR_IO_PENDING, rv);
8273 // Valid change to restricted port should pass.
8274 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118275}
8276
[email protected]23e482282013-06-14 16:08:028277TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238278 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118279 // Ensure that we're not allowed to redirect traffic via an alternate
8280 // protocol to an unrestricted (port >= 1024) when the original traffic was
8281 // on a restricted port (port < 1024). Ensure that we can redirect in all
8282 // other cases.
8283 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118284
8285 HttpRequestInfo unrestricted_port_request;
8286 unrestricted_port_request.method = "GET";
8287 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8288 unrestricted_port_request.load_flags = 0;
8289
[email protected]d973e99a2012-02-17 21:02:368290 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118291 StaticSocketDataProvider first_data;
8292 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078293 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118294
8295 MockRead data_reads[] = {
8296 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8297 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068298 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118299 };
8300 StaticSocketDataProvider second_data(
8301 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078302 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118303
[email protected]bb88e1d32013-05-03 23:11:078304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118305
[email protected]30d4c022013-07-18 22:58:168306 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538307 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118308 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538309 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118310 HostPortPair::FromURL(unrestricted_port_request.url),
8311 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438312 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118313
[email protected]262eec82013-03-19 21:01:368314 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508315 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418316 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118317
[email protected]49639fa2011-12-20 23:22:418318 int rv = trans->Start(
8319 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118320 EXPECT_EQ(ERR_IO_PENDING, rv);
8321 // Valid change to an unrestricted port should pass.
8322 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118323}
8324
[email protected]23e482282013-06-14 16:08:028325TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238326 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028327 // Ensure that we're not allowed to redirect traffic via an alternate
8328 // protocol to an unsafe port, and that we resume the second
8329 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8330 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028331
8332 HttpRequestInfo request;
8333 request.method = "GET";
8334 request.url = GURL("http://www.google.com/");
8335 request.load_flags = 0;
8336
8337 // The alternate protocol request will error out before we attempt to connect,
8338 // so only the standard HTTP request will try to connect.
8339 MockRead data_reads[] = {
8340 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8341 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068342 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028343 };
8344 StaticSocketDataProvider data(
8345 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078346 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028347
[email protected]bb88e1d32013-05-03 23:11:078348 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028349
[email protected]30d4c022013-07-18 22:58:168350 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028351 session->http_server_properties();
8352 const int kUnsafePort = 7;
8353 http_server_properties->SetAlternateProtocol(
8354 HostPortPair::FromURL(request.url),
8355 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438356 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028357
[email protected]262eec82013-03-19 21:01:368358 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508359 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028360 TestCompletionCallback callback;
8361
8362 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8363 EXPECT_EQ(ERR_IO_PENDING, rv);
8364 // The HTTP request should succeed.
8365 EXPECT_EQ(OK, callback.WaitForResult());
8366
8367 // Disable alternate protocol before the asserts.
8368 HttpStreamFactory::set_use_alternate_protocols(false);
8369
8370 const HttpResponseInfo* response = trans->GetResponseInfo();
8371 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508372 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028373 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8374
8375 std::string response_data;
8376 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8377 EXPECT_EQ("hello world", response_data);
8378}
8379
[email protected]23e482282013-06-14 16:08:028380TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388381 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038382 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548383
8384 HttpRequestInfo request;
8385 request.method = "GET";
8386 request.url = GURL("http://www.google.com/");
8387 request.load_flags = 0;
8388
[email protected]8a0fc822013-06-27 20:52:438389 std::string alternate_protocol_http_header =
8390 GetAlternateProtocolHttpHeader();
8391
[email protected]2ff8b312010-04-26 22:20:548392 MockRead data_reads[] = {
8393 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438394 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548395 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178396 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8397 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548398 };
8399
8400 StaticSocketDataProvider first_transaction(
8401 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078402 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548403
[email protected]8ddf8322012-02-23 18:08:068404 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028405 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548407
[email protected]cdf8f7e72013-05-23 10:56:468408 scoped_ptr<SpdyFrame> req(
8409 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138410 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548411
[email protected]23e482282013-06-14 16:08:028412 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8413 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548414 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138415 CreateMockRead(*resp),
8416 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068417 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548418 };
8419
[email protected]dd54bd82012-07-19 23:44:578420 DelayedSocketData spdy_data(
8421 1, // wait for one write to finish before reading.
8422 spdy_reads, arraysize(spdy_reads),
8423 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078424 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548425
[email protected]d973e99a2012-02-17 21:02:368426 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558427 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8428 NULL, 0, NULL, 0);
8429 hanging_non_alternate_protocol_socket.set_connect_data(
8430 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078431 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558432 &hanging_non_alternate_protocol_socket);
8433
[email protected]49639fa2011-12-20 23:22:418434 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548435
[email protected]bb88e1d32013-05-03 23:11:078436 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368437 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508438 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548439
[email protected]49639fa2011-12-20 23:22:418440 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548441 EXPECT_EQ(ERR_IO_PENDING, rv);
8442 EXPECT_EQ(OK, callback.WaitForResult());
8443
8444 const HttpResponseInfo* response = trans->GetResponseInfo();
8445 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508446 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548447 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8448
8449 std::string response_data;
8450 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8451 EXPECT_EQ("hello world", response_data);
8452
[email protected]90499482013-06-01 00:39:508453 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548454
[email protected]49639fa2011-12-20 23:22:418455 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548456 EXPECT_EQ(ERR_IO_PENDING, rv);
8457 EXPECT_EQ(OK, callback.WaitForResult());
8458
8459 response = trans->GetResponseInfo();
8460 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508461 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548462 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538463 EXPECT_TRUE(response->was_fetched_via_spdy);
8464 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548465
8466 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8467 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548468}
8469
[email protected]23e482282013-06-14 16:08:028470TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558471 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038472 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558473
8474 HttpRequestInfo request;
8475 request.method = "GET";
8476 request.url = GURL("http://www.google.com/");
8477 request.load_flags = 0;
8478
[email protected]8a0fc822013-06-27 20:52:438479 std::string alternate_protocol_http_header =
8480 GetAlternateProtocolHttpHeader();
8481
[email protected]2d6728692011-03-12 01:39:558482 MockRead data_reads[] = {
8483 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438484 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558485 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178486 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068487 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558488 };
8489
8490 StaticSocketDataProvider first_transaction(
8491 data_reads, arraysize(data_reads), NULL, 0);
8492 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078493 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558494
[email protected]d973e99a2012-02-17 21:02:368495 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558496 StaticSocketDataProvider hanging_socket(
8497 NULL, 0, NULL, 0);
8498 hanging_socket.set_connect_data(never_finishing_connect);
8499 // Socket 2 and 3 are the hanging Alternate-Protocol and
8500 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078501 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8502 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558503
[email protected]8ddf8322012-02-23 18:08:068504 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028505 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558507
[email protected]cdf8f7e72013-05-23 10:56:468508 scoped_ptr<SpdyFrame> req1(
8509 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8510 scoped_ptr<SpdyFrame> req2(
8511 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558512 MockWrite spdy_writes[] = {
8513 CreateMockWrite(*req1),
8514 CreateMockWrite(*req2),
8515 };
[email protected]23e482282013-06-14 16:08:028516 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8517 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8518 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8519 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558520 MockRead spdy_reads[] = {
8521 CreateMockRead(*resp1),
8522 CreateMockRead(*data1),
8523 CreateMockRead(*resp2),
8524 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068525 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558526 };
8527
[email protected]dd54bd82012-07-19 23:44:578528 DelayedSocketData spdy_data(
8529 2, // wait for writes to finish before reading.
8530 spdy_reads, arraysize(spdy_reads),
8531 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558532 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078533 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558534
8535 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078536 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558537
[email protected]bb88e1d32013-05-03 23:11:078538 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418539 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508540 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558541
[email protected]49639fa2011-12-20 23:22:418542 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558543 EXPECT_EQ(ERR_IO_PENDING, rv);
8544 EXPECT_EQ(OK, callback1.WaitForResult());
8545
8546 const HttpResponseInfo* response = trans1.GetResponseInfo();
8547 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508548 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558549 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8550
8551 std::string response_data;
8552 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8553 EXPECT_EQ("hello world", response_data);
8554
[email protected]49639fa2011-12-20 23:22:418555 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508556 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418557 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558558 EXPECT_EQ(ERR_IO_PENDING, rv);
8559
[email protected]49639fa2011-12-20 23:22:418560 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508561 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418562 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558563 EXPECT_EQ(ERR_IO_PENDING, rv);
8564
8565 EXPECT_EQ(OK, callback2.WaitForResult());
8566 EXPECT_EQ(OK, callback3.WaitForResult());
8567
8568 response = trans2.GetResponseInfo();
8569 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508570 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558571 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8572 EXPECT_TRUE(response->was_fetched_via_spdy);
8573 EXPECT_TRUE(response->was_npn_negotiated);
8574 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8575 EXPECT_EQ("hello!", response_data);
8576
8577 response = trans3.GetResponseInfo();
8578 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508579 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558580 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8581 EXPECT_TRUE(response->was_fetched_via_spdy);
8582 EXPECT_TRUE(response->was_npn_negotiated);
8583 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8584 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558585}
8586
[email protected]23e482282013-06-14 16:08:028587TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558588 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038589 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558590
8591 HttpRequestInfo request;
8592 request.method = "GET";
8593 request.url = GURL("http://www.google.com/");
8594 request.load_flags = 0;
8595
[email protected]8a0fc822013-06-27 20:52:438596 std::string alternate_protocol_http_header =
8597 GetAlternateProtocolHttpHeader();
8598
[email protected]2d6728692011-03-12 01:39:558599 MockRead data_reads[] = {
8600 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438601 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558602 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178603 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068604 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558605 };
8606
8607 StaticSocketDataProvider first_transaction(
8608 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078609 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558610
[email protected]8ddf8322012-02-23 18:08:068611 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028612 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558614
[email protected]d973e99a2012-02-17 21:02:368615 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558616 StaticSocketDataProvider hanging_alternate_protocol_socket(
8617 NULL, 0, NULL, 0);
8618 hanging_alternate_protocol_socket.set_connect_data(
8619 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078620 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558621 &hanging_alternate_protocol_socket);
8622
8623 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078624 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558625
[email protected]49639fa2011-12-20 23:22:418626 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558627
[email protected]bb88e1d32013-05-03 23:11:078628 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368629 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508630 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558631
[email protected]49639fa2011-12-20 23:22:418632 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558633 EXPECT_EQ(ERR_IO_PENDING, rv);
8634 EXPECT_EQ(OK, callback.WaitForResult());
8635
8636 const HttpResponseInfo* response = trans->GetResponseInfo();
8637 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508638 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558639 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8640
8641 std::string response_data;
8642 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8643 EXPECT_EQ("hello world", response_data);
8644
[email protected]90499482013-06-01 00:39:508645 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558646
[email protected]49639fa2011-12-20 23:22:418647 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558648 EXPECT_EQ(ERR_IO_PENDING, rv);
8649 EXPECT_EQ(OK, callback.WaitForResult());
8650
8651 response = trans->GetResponseInfo();
8652 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508653 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558654 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8655 EXPECT_FALSE(response->was_fetched_via_spdy);
8656 EXPECT_FALSE(response->was_npn_negotiated);
8657
8658 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8659 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558660}
8661
[email protected]631f1322010-04-30 17:59:118662class CapturingProxyResolver : public ProxyResolver {
8663 public:
8664 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8665 virtual ~CapturingProxyResolver() {}
8666
8667 virtual int GetProxyForURL(const GURL& url,
8668 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318669 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118670 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168671 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408672 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8673 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428674 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118675 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428676 return OK;
[email protected]631f1322010-04-30 17:59:118677 }
8678
[email protected]46fadfd2013-02-06 09:40:168679 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118680 NOTREACHED();
8681 }
8682
[email protected]f2c971f2011-11-08 00:33:178683 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8684 NOTREACHED();
8685 return LOAD_STATE_IDLE;
8686 }
8687
[email protected]46fadfd2013-02-06 09:40:168688 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408689 NOTREACHED();
8690 }
8691
[email protected]24476402010-07-20 20:55:178692 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168693 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428694 return OK;
[email protected]631f1322010-04-30 17:59:118695 }
8696
[email protected]24476402010-07-20 20:55:178697 const std::vector<GURL>& resolved() const { return resolved_; }
8698
8699 private:
[email protected]631f1322010-04-30 17:59:118700 std::vector<GURL> resolved_;
8701
8702 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8703};
8704
[email protected]23e482282013-06-14 16:08:028705TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238706 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388707 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038708 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118709
8710 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428711 proxy_config.set_auto_detect(true);
8712 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118713
[email protected]631f1322010-04-30 17:59:118714 CapturingProxyResolver* capturing_proxy_resolver =
8715 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078716 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388717 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8718 NULL));
[email protected]029c83b62013-01-24 05:28:208719 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078720 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118721
8722 HttpRequestInfo request;
8723 request.method = "GET";
8724 request.url = GURL("http://www.google.com/");
8725 request.load_flags = 0;
8726
[email protected]8a0fc822013-06-27 20:52:438727 std::string alternate_protocol_http_header =
8728 GetAlternateProtocolHttpHeader();
8729
[email protected]631f1322010-04-30 17:59:118730 MockRead data_reads[] = {
8731 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438732 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118733 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178734 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068735 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118736 };
8737
8738 StaticSocketDataProvider first_transaction(
8739 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078740 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:118741
[email protected]8ddf8322012-02-23 18:08:068742 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028743 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:118745
[email protected]cdf8f7e72013-05-23 10:56:468746 scoped_ptr<SpdyFrame> req(
8747 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:118748 MockWrite spdy_writes[] = {
8749 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8750 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:428751 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:468752 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:118753 };
8754
[email protected]d911f1b2010-05-05 22:39:428755 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8756
[email protected]23e482282013-06-14 16:08:028757 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8758 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:118759 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068760 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:138761 CreateMockRead(*resp.get(), 4), // 2, 4
8762 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:068763 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:118764 };
8765
[email protected]dd54bd82012-07-19 23:44:578766 OrderedSocketData spdy_data(
8767 spdy_reads, arraysize(spdy_reads),
8768 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078769 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:118770
[email protected]d973e99a2012-02-17 21:02:368771 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558772 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8773 NULL, 0, NULL, 0);
8774 hanging_non_alternate_protocol_socket.set_connect_data(
8775 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078776 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558777 &hanging_non_alternate_protocol_socket);
8778
[email protected]49639fa2011-12-20 23:22:418779 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:118780
[email protected]bb88e1d32013-05-03 23:11:078781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368782 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118784
[email protected]49639fa2011-12-20 23:22:418785 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118786 EXPECT_EQ(ERR_IO_PENDING, rv);
8787 EXPECT_EQ(OK, callback.WaitForResult());
8788
8789 const HttpResponseInfo* response = trans->GetResponseInfo();
8790 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508791 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118792 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538793 EXPECT_FALSE(response->was_fetched_via_spdy);
8794 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118795
8796 std::string response_data;
8797 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8798 EXPECT_EQ("hello world", response_data);
8799
[email protected]90499482013-06-01 00:39:508800 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118801
[email protected]49639fa2011-12-20 23:22:418802 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118803 EXPECT_EQ(ERR_IO_PENDING, rv);
8804 EXPECT_EQ(OK, callback.WaitForResult());
8805
8806 response = trans->GetResponseInfo();
8807 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508808 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118809 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538810 EXPECT_TRUE(response->was_fetched_via_spdy);
8811 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118812
8813 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8814 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558815 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:428816 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:118817 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:428818 EXPECT_EQ("https://www.google.com/",
8819 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:118820
[email protected]029c83b62013-01-24 05:28:208821 LoadTimingInfo load_timing_info;
8822 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8823 TestLoadTimingNotReusedWithPac(load_timing_info,
8824 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:118825}
[email protected]631f1322010-04-30 17:59:118826
[email protected]23e482282013-06-14 16:08:028827TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:548828 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:388829 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038830 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548831
8832 HttpRequestInfo request;
8833 request.method = "GET";
8834 request.url = GURL("http://www.google.com/");
8835 request.load_flags = 0;
8836
[email protected]8a0fc822013-06-27 20:52:438837 std::string alternate_protocol_http_header =
8838 GetAlternateProtocolHttpHeader();
8839
[email protected]2ff8b312010-04-26 22:20:548840 MockRead data_reads[] = {
8841 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438842 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548843 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068844 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:548845 };
8846
8847 StaticSocketDataProvider first_transaction(
8848 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078849 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548850
[email protected]8ddf8322012-02-23 18:08:068851 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028852 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078853 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548854
[email protected]cdf8f7e72013-05-23 10:56:468855 scoped_ptr<SpdyFrame> req(
8856 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138857 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548858
[email protected]23e482282013-06-14 16:08:028859 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8860 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548861 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138862 CreateMockRead(*resp),
8863 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068864 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548865 };
8866
[email protected]dd54bd82012-07-19 23:44:578867 DelayedSocketData spdy_data(
8868 1, // wait for one write to finish before reading.
8869 spdy_reads, arraysize(spdy_reads),
8870 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078871 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548872
[email protected]83039bb2011-12-09 18:43:558873 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548874
[email protected]bb88e1d32013-05-03 23:11:078875 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:548876
[email protected]262eec82013-03-19 21:01:368877 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548879
[email protected]49639fa2011-12-20 23:22:418880 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548881 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418882 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548883
8884 const HttpResponseInfo* response = trans->GetResponseInfo();
8885 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508886 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548887 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8888
8889 std::string response_data;
8890 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8891 EXPECT_EQ("hello world", response_data);
8892
8893 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:388894 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:408895 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
8896 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:278897 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:268898 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:388899
[email protected]90499482013-06-01 00:39:508900 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548901
[email protected]49639fa2011-12-20 23:22:418902 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548903 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418904 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548905
8906 response = trans->GetResponseInfo();
8907 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508908 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538910 EXPECT_TRUE(response->was_fetched_via_spdy);
8911 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548912
8913 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8914 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:428915}
8916
[email protected]044de0642010-06-17 10:42:158917// GenerateAuthToken is a mighty big test.
8918// It tests all permutation of GenerateAuthToken behavior:
8919// - Synchronous and Asynchronous completion.
8920// - OK or error on completion.
8921// - Direct connection, non-authenticating proxy, and authenticating proxy.
8922// - HTTP or HTTPS backend (to include proxy tunneling).
8923// - Non-authenticating and authenticating backend.
8924//
[email protected]fe3b7dc2012-02-03 19:52:098925// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:158926// problems generating an auth token for an authenticating proxy, we don't
8927// need to test all permutations of the backend server).
8928//
8929// The test proceeds by going over each of the configuration cases, and
8930// potentially running up to three rounds in each of the tests. The TestConfig
8931// specifies both the configuration for the test as well as the expectations
8932// for the results.
[email protected]23e482282013-06-14 16:08:028933TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:508934 static const char kServer[] = "http://www.example.com";
8935 static const char kSecureServer[] = "https://www.example.com";
8936 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:158937 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
8938
8939 enum AuthTiming {
8940 AUTH_NONE,
8941 AUTH_SYNC,
8942 AUTH_ASYNC,
8943 };
8944
8945 const MockWrite kGet(
8946 "GET / HTTP/1.1\r\n"
8947 "Host: www.example.com\r\n"
8948 "Connection: keep-alive\r\n\r\n");
8949 const MockWrite kGetProxy(
8950 "GET http://www.example.com/ HTTP/1.1\r\n"
8951 "Host: www.example.com\r\n"
8952 "Proxy-Connection: keep-alive\r\n\r\n");
8953 const MockWrite kGetAuth(
8954 "GET / HTTP/1.1\r\n"
8955 "Host: www.example.com\r\n"
8956 "Connection: keep-alive\r\n"
8957 "Authorization: auth_token\r\n\r\n");
8958 const MockWrite kGetProxyAuth(
8959 "GET http://www.example.com/ HTTP/1.1\r\n"
8960 "Host: www.example.com\r\n"
8961 "Proxy-Connection: keep-alive\r\n"
8962 "Proxy-Authorization: auth_token\r\n\r\n");
8963 const MockWrite kGetAuthThroughProxy(
8964 "GET http://www.example.com/ HTTP/1.1\r\n"
8965 "Host: www.example.com\r\n"
8966 "Proxy-Connection: keep-alive\r\n"
8967 "Authorization: auth_token\r\n\r\n");
8968 const MockWrite kGetAuthWithProxyAuth(
8969 "GET http://www.example.com/ HTTP/1.1\r\n"
8970 "Host: www.example.com\r\n"
8971 "Proxy-Connection: keep-alive\r\n"
8972 "Proxy-Authorization: auth_token\r\n"
8973 "Authorization: auth_token\r\n\r\n");
8974 const MockWrite kConnect(
8975 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8976 "Host: www.example.com\r\n"
8977 "Proxy-Connection: keep-alive\r\n\r\n");
8978 const MockWrite kConnectProxyAuth(
8979 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8980 "Host: www.example.com\r\n"
8981 "Proxy-Connection: keep-alive\r\n"
8982 "Proxy-Authorization: auth_token\r\n\r\n");
8983
8984 const MockRead kSuccess(
8985 "HTTP/1.1 200 OK\r\n"
8986 "Content-Type: text/html; charset=iso-8859-1\r\n"
8987 "Content-Length: 3\r\n\r\n"
8988 "Yes");
8989 const MockRead kFailure(
8990 "Should not be called.");
8991 const MockRead kServerChallenge(
8992 "HTTP/1.1 401 Unauthorized\r\n"
8993 "WWW-Authenticate: Mock realm=server\r\n"
8994 "Content-Type: text/html; charset=iso-8859-1\r\n"
8995 "Content-Length: 14\r\n\r\n"
8996 "Unauthorized\r\n");
8997 const MockRead kProxyChallenge(
8998 "HTTP/1.1 407 Unauthorized\r\n"
8999 "Proxy-Authenticate: Mock realm=proxy\r\n"
9000 "Proxy-Connection: close\r\n"
9001 "Content-Type: text/html; charset=iso-8859-1\r\n"
9002 "Content-Length: 14\r\n\r\n"
9003 "Unauthorized\r\n");
9004 const MockRead kProxyConnected(
9005 "HTTP/1.1 200 Connection Established\r\n\r\n");
9006
9007 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9008 // no constructors, but the C++ compiler on Windows warns about
9009 // unspecified data in compound literals. So, moved to using constructors,
9010 // and TestRound's created with the default constructor should not be used.
9011 struct TestRound {
9012 TestRound()
9013 : expected_rv(ERR_UNEXPECTED),
9014 extra_write(NULL),
9015 extra_read(NULL) {
9016 }
9017 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9018 int expected_rv_arg)
9019 : write(write_arg),
9020 read(read_arg),
9021 expected_rv(expected_rv_arg),
9022 extra_write(NULL),
9023 extra_read(NULL) {
9024 }
9025 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9026 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019027 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159028 : write(write_arg),
9029 read(read_arg),
9030 expected_rv(expected_rv_arg),
9031 extra_write(extra_write_arg),
9032 extra_read(extra_read_arg) {
9033 }
9034 MockWrite write;
9035 MockRead read;
9036 int expected_rv;
9037 const MockWrite* extra_write;
9038 const MockRead* extra_read;
9039 };
9040
9041 static const int kNoSSL = 500;
9042
9043 struct TestConfig {
9044 const char* proxy_url;
9045 AuthTiming proxy_auth_timing;
9046 int proxy_auth_rv;
9047 const char* server_url;
9048 AuthTiming server_auth_timing;
9049 int server_auth_rv;
9050 int num_auth_rounds;
9051 int first_ssl_round;
9052 TestRound rounds[3];
9053 } test_configs[] = {
9054 // Non-authenticating HTTP server with a direct connection.
9055 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9056 { TestRound(kGet, kSuccess, OK)}},
9057 // Authenticating HTTP server with a direct connection.
9058 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9059 { TestRound(kGet, kServerChallenge, OK),
9060 TestRound(kGetAuth, kSuccess, OK)}},
9061 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9062 { TestRound(kGet, kServerChallenge, OK),
9063 TestRound(kGetAuth, kFailure, kAuthErr)}},
9064 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9065 { TestRound(kGet, kServerChallenge, OK),
9066 TestRound(kGetAuth, kSuccess, OK)}},
9067 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9068 { TestRound(kGet, kServerChallenge, OK),
9069 TestRound(kGetAuth, kFailure, kAuthErr)}},
9070 // Non-authenticating HTTP server through a non-authenticating proxy.
9071 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9072 { TestRound(kGetProxy, kSuccess, OK)}},
9073 // Authenticating HTTP server through a non-authenticating proxy.
9074 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9075 { TestRound(kGetProxy, kServerChallenge, OK),
9076 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9077 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9078 { TestRound(kGetProxy, kServerChallenge, OK),
9079 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9080 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9081 { TestRound(kGetProxy, kServerChallenge, OK),
9082 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9083 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9084 { TestRound(kGetProxy, kServerChallenge, OK),
9085 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9086 // Non-authenticating HTTP server through an authenticating proxy.
9087 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9088 { TestRound(kGetProxy, kProxyChallenge, OK),
9089 TestRound(kGetProxyAuth, kSuccess, OK)}},
9090 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9091 { TestRound(kGetProxy, kProxyChallenge, OK),
9092 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9093 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9094 { TestRound(kGetProxy, kProxyChallenge, OK),
9095 TestRound(kGetProxyAuth, kSuccess, OK)}},
9096 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9097 { TestRound(kGetProxy, kProxyChallenge, OK),
9098 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9099 // Authenticating HTTP server through an authenticating proxy.
9100 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9101 { TestRound(kGetProxy, kProxyChallenge, OK),
9102 TestRound(kGetProxyAuth, kServerChallenge, OK),
9103 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9104 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9105 { TestRound(kGetProxy, kProxyChallenge, OK),
9106 TestRound(kGetProxyAuth, kServerChallenge, OK),
9107 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9108 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9109 { TestRound(kGetProxy, kProxyChallenge, OK),
9110 TestRound(kGetProxyAuth, kServerChallenge, OK),
9111 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9112 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9113 { TestRound(kGetProxy, kProxyChallenge, OK),
9114 TestRound(kGetProxyAuth, kServerChallenge, OK),
9115 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9116 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9117 { TestRound(kGetProxy, kProxyChallenge, OK),
9118 TestRound(kGetProxyAuth, kServerChallenge, OK),
9119 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9120 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9121 { TestRound(kGetProxy, kProxyChallenge, OK),
9122 TestRound(kGetProxyAuth, kServerChallenge, OK),
9123 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9124 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9125 { TestRound(kGetProxy, kProxyChallenge, OK),
9126 TestRound(kGetProxyAuth, kServerChallenge, OK),
9127 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9128 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9129 { TestRound(kGetProxy, kProxyChallenge, OK),
9130 TestRound(kGetProxyAuth, kServerChallenge, OK),
9131 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9132 // Non-authenticating HTTPS server with a direct connection.
9133 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9134 { TestRound(kGet, kSuccess, OK)}},
9135 // Authenticating HTTPS server with a direct connection.
9136 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9137 { TestRound(kGet, kServerChallenge, OK),
9138 TestRound(kGetAuth, kSuccess, OK)}},
9139 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9140 { TestRound(kGet, kServerChallenge, OK),
9141 TestRound(kGetAuth, kFailure, kAuthErr)}},
9142 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9143 { TestRound(kGet, kServerChallenge, OK),
9144 TestRound(kGetAuth, kSuccess, OK)}},
9145 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9146 { TestRound(kGet, kServerChallenge, OK),
9147 TestRound(kGetAuth, kFailure, kAuthErr)}},
9148 // Non-authenticating HTTPS server with a non-authenticating proxy.
9149 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9150 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9151 // Authenticating HTTPS server through a non-authenticating proxy.
9152 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9153 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9154 TestRound(kGetAuth, kSuccess, OK)}},
9155 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9156 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9157 TestRound(kGetAuth, kFailure, kAuthErr)}},
9158 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9159 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9160 TestRound(kGetAuth, kSuccess, OK)}},
9161 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9162 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9163 TestRound(kGetAuth, kFailure, kAuthErr)}},
9164 // Non-Authenticating HTTPS server through an authenticating proxy.
9165 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9166 { TestRound(kConnect, kProxyChallenge, OK),
9167 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9168 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9169 { TestRound(kConnect, kProxyChallenge, OK),
9170 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9171 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9172 { TestRound(kConnect, kProxyChallenge, OK),
9173 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9174 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9175 { TestRound(kConnect, kProxyChallenge, OK),
9176 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9177 // Authenticating HTTPS server through an authenticating proxy.
9178 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9179 { TestRound(kConnect, kProxyChallenge, OK),
9180 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9181 &kGet, &kServerChallenge),
9182 TestRound(kGetAuth, kSuccess, OK)}},
9183 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9184 { TestRound(kConnect, kProxyChallenge, OK),
9185 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9186 &kGet, &kServerChallenge),
9187 TestRound(kGetAuth, kFailure, kAuthErr)}},
9188 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9189 { TestRound(kConnect, kProxyChallenge, OK),
9190 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9191 &kGet, &kServerChallenge),
9192 TestRound(kGetAuth, kSuccess, OK)}},
9193 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9194 { TestRound(kConnect, kProxyChallenge, OK),
9195 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9196 &kGet, &kServerChallenge),
9197 TestRound(kGetAuth, kFailure, kAuthErr)}},
9198 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9199 { TestRound(kConnect, kProxyChallenge, OK),
9200 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9201 &kGet, &kServerChallenge),
9202 TestRound(kGetAuth, kSuccess, OK)}},
9203 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9204 { TestRound(kConnect, kProxyChallenge, OK),
9205 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9206 &kGet, &kServerChallenge),
9207 TestRound(kGetAuth, kFailure, kAuthErr)}},
9208 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9209 { TestRound(kConnect, kProxyChallenge, OK),
9210 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9211 &kGet, &kServerChallenge),
9212 TestRound(kGetAuth, kSuccess, OK)}},
9213 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9214 { TestRound(kConnect, kProxyChallenge, OK),
9215 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9216 &kGet, &kServerChallenge),
9217 TestRound(kGetAuth, kFailure, kAuthErr)}},
9218 };
9219
[email protected]044de0642010-06-17 10:42:159220 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089221 HttpAuthHandlerMock::Factory* auth_factory(
9222 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079223 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159224 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269225
9226 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159227 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089228 for (int n = 0; n < 2; n++) {
9229 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9230 std::string auth_challenge = "Mock realm=proxy";
9231 GURL origin(test_config.proxy_url);
9232 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9233 auth_challenge.end());
9234 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9235 origin, BoundNetLog());
9236 auth_handler->SetGenerateExpectation(
9237 test_config.proxy_auth_timing == AUTH_ASYNC,
9238 test_config.proxy_auth_rv);
9239 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9240 }
[email protected]044de0642010-06-17 10:42:159241 }
9242 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009243 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159244 std::string auth_challenge = "Mock realm=server";
9245 GURL origin(test_config.server_url);
9246 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9247 auth_challenge.end());
9248 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9249 origin, BoundNetLog());
9250 auth_handler->SetGenerateExpectation(
9251 test_config.server_auth_timing == AUTH_ASYNC,
9252 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089253 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159254 }
9255 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079256 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129257 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159258 } else {
[email protected]bb88e1d32013-05-03 23:11:079259 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159260 }
9261
9262 HttpRequestInfo request;
9263 request.method = "GET";
9264 request.url = GURL(test_config.server_url);
9265 request.load_flags = 0;
9266
[email protected]bb88e1d32013-05-03 23:11:079267 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079268 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159269
9270 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9271 const TestRound& read_write_round = test_config.rounds[round];
9272
9273 // Set up expected reads and writes.
9274 MockRead reads[2];
9275 reads[0] = read_write_round.read;
9276 size_t length_reads = 1;
9277 if (read_write_round.extra_read) {
9278 reads[1] = *read_write_round.extra_read;
9279 length_reads = 2;
9280 }
9281
9282 MockWrite writes[2];
9283 writes[0] = read_write_round.write;
9284 size_t length_writes = 1;
9285 if (read_write_round.extra_write) {
9286 writes[1] = *read_write_round.extra_write;
9287 length_writes = 2;
9288 }
9289 StaticSocketDataProvider data_provider(
9290 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079291 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159292
9293 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069294 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159295 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079296 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159297 &ssl_socket_data_provider);
9298
9299 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419300 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159301 int rv;
9302 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419303 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159304 } else {
[email protected]49639fa2011-12-20 23:22:419305 rv = trans.RestartWithAuth(
9306 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159307 }
9308 if (rv == ERR_IO_PENDING)
9309 rv = callback.WaitForResult();
9310
9311 // Compare results with expected data.
9312 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509313 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159314 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509315 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159316 } else {
9317 EXPECT_TRUE(response == NULL);
9318 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9319 continue;
9320 }
9321 if (round + 1 < test_config.num_auth_rounds) {
9322 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9323 } else {
9324 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9325 }
9326 }
[email protected]e5ae96a2010-04-14 20:12:459327 }
9328}
9329
[email protected]23e482282013-06-14 16:08:029330TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149331 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149332 HttpAuthHandlerMock::Factory* auth_factory(
9333 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079334 session_deps_.http_auth_handler_factory.reset(auth_factory);
9335 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9336 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9337 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149338
9339 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9340 auth_handler->set_connection_based(true);
9341 std::string auth_challenge = "Mock realm=server";
9342 GURL origin("http://www.example.com");
9343 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9344 auth_challenge.end());
9345 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9346 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089347 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149348
[email protected]c871bce92010-07-15 21:51:149349 int rv = OK;
9350 const HttpResponseInfo* response = NULL;
9351 HttpRequestInfo request;
9352 request.method = "GET";
9353 request.url = origin;
9354 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279355
[email protected]bb88e1d32013-05-03 23:11:079356 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109357
9358 // Use a TCP Socket Pool with only one connection per group. This is used
9359 // to validate that the TCP socket is not released to the pool between
9360 // each round of multi-round authentication.
9361 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289362 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9363 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109364 50, // Max sockets for pool
9365 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289366 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079367 session_deps_.host_resolver.get(),
9368 session_deps_.socket_factory.get(),
9369 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449370 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9371 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029372 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449373 session_peer.SetClientSocketPoolManager(
9374 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109375
[email protected]262eec82013-03-19 21:01:369376 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419378 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149379
9380 const MockWrite kGet(
9381 "GET / HTTP/1.1\r\n"
9382 "Host: www.example.com\r\n"
9383 "Connection: keep-alive\r\n\r\n");
9384 const MockWrite kGetAuth(
9385 "GET / HTTP/1.1\r\n"
9386 "Host: www.example.com\r\n"
9387 "Connection: keep-alive\r\n"
9388 "Authorization: auth_token\r\n\r\n");
9389
9390 const MockRead kServerChallenge(
9391 "HTTP/1.1 401 Unauthorized\r\n"
9392 "WWW-Authenticate: Mock realm=server\r\n"
9393 "Content-Type: text/html; charset=iso-8859-1\r\n"
9394 "Content-Length: 14\r\n\r\n"
9395 "Unauthorized\r\n");
9396 const MockRead kSuccess(
9397 "HTTP/1.1 200 OK\r\n"
9398 "Content-Type: text/html; charset=iso-8859-1\r\n"
9399 "Content-Length: 3\r\n\r\n"
9400 "Yes");
9401
9402 MockWrite writes[] = {
9403 // First round
9404 kGet,
9405 // Second round
9406 kGetAuth,
9407 // Third round
9408 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309409 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109410 kGetAuth,
9411 // Competing request
9412 kGet,
[email protected]c871bce92010-07-15 21:51:149413 };
9414 MockRead reads[] = {
9415 // First round
9416 kServerChallenge,
9417 // Second round
9418 kServerChallenge,
9419 // Third round
[email protected]eca50e122010-09-11 14:03:309420 kServerChallenge,
9421 // Fourth round
[email protected]c871bce92010-07-15 21:51:149422 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109423 // Competing response
9424 kSuccess,
[email protected]c871bce92010-07-15 21:51:149425 };
9426 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9427 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079428 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149429
[email protected]7ef4cbbb2011-02-06 11:19:109430 const char* const kSocketGroup = "www.example.com:80";
9431
9432 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149433 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419434 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149435 if (rv == ERR_IO_PENDING)
9436 rv = callback.WaitForResult();
9437 EXPECT_EQ(OK, rv);
9438 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509439 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149440 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289441 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149442
[email protected]7ef4cbbb2011-02-06 11:19:109443 // In between rounds, another request comes in for the same domain.
9444 // It should not be able to grab the TCP socket that trans has already
9445 // claimed.
9446 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509447 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419448 TestCompletionCallback callback_compete;
9449 rv = trans_compete->Start(
9450 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109451 EXPECT_EQ(ERR_IO_PENDING, rv);
9452 // callback_compete.WaitForResult at this point would stall forever,
9453 // since the HttpNetworkTransaction does not release the request back to
9454 // the pool until after authentication completes.
9455
9456 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149457 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419458 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149459 if (rv == ERR_IO_PENDING)
9460 rv = callback.WaitForResult();
9461 EXPECT_EQ(OK, rv);
9462 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509463 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149464 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289465 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149466
[email protected]7ef4cbbb2011-02-06 11:19:109467 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149468 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419469 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149470 if (rv == ERR_IO_PENDING)
9471 rv = callback.WaitForResult();
9472 EXPECT_EQ(OK, rv);
9473 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509474 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149475 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289476 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309477
[email protected]7ef4cbbb2011-02-06 11:19:109478 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309479 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419480 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309481 if (rv == ERR_IO_PENDING)
9482 rv = callback.WaitForResult();
9483 EXPECT_EQ(OK, rv);
9484 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509485 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309486 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289487 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109488
9489 // Read the body since the fourth round was successful. This will also
9490 // release the socket back to the pool.
9491 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509492 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109493 if (rv == ERR_IO_PENDING)
9494 rv = callback.WaitForResult();
9495 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509496 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109497 EXPECT_EQ(0, rv);
9498 // There are still 0 idle sockets, since the trans_compete transaction
9499 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289500 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109501
9502 // The competing request can now finish. Wait for the headers and then
9503 // read the body.
9504 rv = callback_compete.WaitForResult();
9505 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509506 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109507 if (rv == ERR_IO_PENDING)
9508 rv = callback.WaitForResult();
9509 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509510 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109511 EXPECT_EQ(0, rv);
9512
9513 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289514 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149515}
9516
[email protected]65041fa2010-05-21 06:56:539517// This tests the case that a request is issued via http instead of spdy after
9518// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029519TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389520 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169521 std::vector<NextProto> next_protos;
9522 next_protos.push_back(kProtoHTTP11);
9523 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539524 HttpRequestInfo request;
9525 request.method = "GET";
9526 request.url = GURL("https://www.google.com/");
9527 request.load_flags = 0;
9528
9529 MockWrite data_writes[] = {
9530 MockWrite("GET / HTTP/1.1\r\n"
9531 "Host: www.google.com\r\n"
9532 "Connection: keep-alive\r\n\r\n"),
9533 };
9534
[email protected]8a0fc822013-06-27 20:52:439535 std::string alternate_protocol_http_header =
9536 GetAlternateProtocolHttpHeader();
9537
[email protected]65041fa2010-05-21 06:56:539538 MockRead data_reads[] = {
9539 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439540 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539541 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069542 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539543 };
9544
[email protected]8ddf8322012-02-23 18:08:069545 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539546 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9547 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469548 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539549
[email protected]bb88e1d32013-05-03 23:11:079550 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539551
9552 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9553 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079554 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539555
[email protected]49639fa2011-12-20 23:22:419556 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539557
[email protected]bb88e1d32013-05-03 23:11:079558 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369559 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539561
[email protected]49639fa2011-12-20 23:22:419562 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539563
9564 EXPECT_EQ(ERR_IO_PENDING, rv);
9565 EXPECT_EQ(OK, callback.WaitForResult());
9566
9567 const HttpResponseInfo* response = trans->GetResponseInfo();
9568 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509569 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539570 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9571
9572 std::string response_data;
9573 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9574 EXPECT_EQ("hello world", response_data);
9575
9576 EXPECT_FALSE(response->was_fetched_via_spdy);
9577 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539578}
[email protected]26ef6582010-06-24 02:30:479579
[email protected]23e482282013-06-14 16:08:029580TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479581 // Simulate the SSL handshake completing with an NPN negotiation
9582 // followed by an immediate server closing of the socket.
9583 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389584 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039585 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479586
9587 HttpRequestInfo request;
9588 request.method = "GET";
9589 request.url = GURL("https://www.google.com/");
9590 request.load_flags = 0;
9591
[email protected]8ddf8322012-02-23 18:08:069592 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029593 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079594 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479595
[email protected]cdf8f7e72013-05-23 10:56:469596 scoped_ptr<SpdyFrame> req(
9597 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139598 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479599
9600 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069601 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479602 };
9603
[email protected]dd54bd82012-07-19 23:44:579604 DelayedSocketData spdy_data(
9605 0, // don't wait in this case, immediate hangup.
9606 spdy_reads, arraysize(spdy_reads),
9607 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079608 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479609
[email protected]49639fa2011-12-20 23:22:419610 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479611
[email protected]bb88e1d32013-05-03 23:11:079612 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369613 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509614 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479615
[email protected]49639fa2011-12-20 23:22:419616 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479617 EXPECT_EQ(ERR_IO_PENDING, rv);
9618 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479619}
[email protected]65d34382010-07-01 18:12:269620
[email protected]795cbf82013-07-22 09:37:279621// A subclass of HttpAuthHandlerMock that records the request URL when
9622// it gets it. This is needed since the auth handler may get destroyed
9623// before we get a chance to query it.
9624class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9625 public:
9626 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9627
9628 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9629
9630 protected:
9631 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9632 const HttpRequestInfo* request,
9633 const CompletionCallback& callback,
9634 std::string* auth_token) OVERRIDE {
9635 *url_ = request->url;
9636 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9637 credentials, request, callback, auth_token);
9638 }
9639
9640 private:
9641 GURL* url_;
9642};
9643
[email protected]23e482282013-06-14 16:08:029644TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309645 // This test ensures that the URL passed into the proxy is upgraded
9646 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389647 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439648 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309649
[email protected]bb88e1d32013-05-03 23:11:079650 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209651 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9652 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079653 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279654 GURL request_url;
9655 {
9656 HttpAuthHandlerMock::Factory* auth_factory =
9657 new HttpAuthHandlerMock::Factory();
9658 UrlRecordingHttpAuthHandlerMock* auth_handler =
9659 new UrlRecordingHttpAuthHandlerMock(&request_url);
9660 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9661 auth_factory->set_do_init_from_challenge(true);
9662 session_deps_.http_auth_handler_factory.reset(auth_factory);
9663 }
[email protected]f45c1ee2010-08-03 00:54:309664
9665 HttpRequestInfo request;
9666 request.method = "GET";
9667 request.url = GURL("http://www.google.com");
9668 request.load_flags = 0;
9669
9670 // First round goes unauthenticated through the proxy.
9671 MockWrite data_writes_1[] = {
9672 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9673 "Host: www.google.com\r\n"
9674 "Proxy-Connection: keep-alive\r\n"
9675 "\r\n"),
9676 };
9677 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069678 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309679 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239680 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309681 "Proxy-Connection: close\r\n"
9682 "\r\n"),
9683 };
9684 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9685 data_writes_1, arraysize(data_writes_1));
9686
9687 // Second round tries to tunnel to www.google.com due to the
9688 // Alternate-Protocol announcement in the first round. It fails due
9689 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599690 // After the failure, a tunnel is established to www.google.com using
9691 // Proxy-Authorization headers. There is then a SPDY request round.
9692 //
[email protected]fe3b7dc2012-02-03 19:52:099693 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9694 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9695 // does a Disconnect and Connect on the same socket, rather than trying
9696 // to obtain a new one.
9697 //
[email protected]394816e92010-08-03 07:38:599698 // NOTE: Originally, the proxy response to the second CONNECT request
9699 // simply returned another 407 so the unit test could skip the SSL connection
9700 // establishment and SPDY framing issues. Alas, the
9701 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309702 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599703
[email protected]cdf8f7e72013-05-23 10:56:469704 scoped_ptr<SpdyFrame> req(
9705 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029706 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9707 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309708
[email protected]394816e92010-08-03 07:38:599709 MockWrite data_writes_2[] = {
9710 // First connection attempt without Proxy-Authorization.
9711 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9712 "Host: www.google.com\r\n"
9713 "Proxy-Connection: keep-alive\r\n"
9714 "\r\n"),
9715
9716 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309717 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9718 "Host: www.google.com\r\n"
9719 "Proxy-Connection: keep-alive\r\n"
9720 "Proxy-Authorization: auth_token\r\n"
9721 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309722
[email protected]394816e92010-08-03 07:38:599723 // SPDY request
9724 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309725 };
[email protected]394816e92010-08-03 07:38:599726 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9727 "Proxy-Authenticate: Mock\r\n"
9728 "Proxy-Connection: close\r\n"
9729 "\r\n");
9730 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9731 MockRead data_reads_2[] = {
9732 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069733 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9734 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599735 arraysize(kRejectConnectResponse) - 1, 1),
9736
9737 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069738 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:099739 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:599740
9741 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:099742 CreateMockRead(*resp.get(), 6),
9743 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:069744 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:599745 };
[email protected]dd54bd82012-07-19 23:44:579746 OrderedSocketData data_2(
9747 data_reads_2, arraysize(data_reads_2),
9748 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:309749
[email protected]8ddf8322012-02-23 18:08:069750 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029751 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:309752
[email protected]d973e99a2012-02-17 21:02:369753 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559754 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9755 NULL, 0, NULL, 0);
9756 hanging_non_alternate_protocol_socket.set_connect_data(
9757 never_finishing_connect);
9758
[email protected]bb88e1d32013-05-03 23:11:079759 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9760 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9762 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559763 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:079764 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:309765
9766 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:419767 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:369768 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:509769 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419770 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309771 EXPECT_EQ(ERR_IO_PENDING, rv);
9772 EXPECT_EQ(OK, callback_1.WaitForResult());
9773
9774 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:419775 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:369776 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:509777 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419778 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309779 EXPECT_EQ(ERR_IO_PENDING, rv);
9780 EXPECT_EQ(OK, callback_2.WaitForResult());
9781 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509782 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:309783 ASSERT_FALSE(response->auth_challenge.get() == NULL);
9784
9785 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:419786 TestCompletionCallback callback_3;
9787 rv = trans_2->RestartWithAuth(
9788 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:309789 EXPECT_EQ(ERR_IO_PENDING, rv);
9790 EXPECT_EQ(OK, callback_3.WaitForResult());
9791
9792 // After all that work, these two lines (or actually, just the scheme) are
9793 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:309794 EXPECT_EQ("https", request_url.scheme());
9795 EXPECT_EQ("www.google.com", request_url.host());
9796
[email protected]029c83b62013-01-24 05:28:209797 LoadTimingInfo load_timing_info;
9798 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9799 TestLoadTimingNotReusedWithPac(load_timing_info,
9800 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:389801}
9802
9803// Test that if we cancel the transaction as the connection is completing, that
9804// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:029805TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:389806 // Setup everything about the connection to complete synchronously, so that
9807 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9808 // for is the callback from the HttpStreamRequest.
9809 // Then cancel the transaction.
9810 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:369811 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:389812 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069813 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9814 MockRead(SYNCHRONOUS, "hello world"),
9815 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:389816 };
9817
[email protected]8e6441ca2010-08-19 05:56:389818 HttpRequestInfo request;
9819 request.method = "GET";
9820 request.url = GURL("http://www.google.com/");
9821 request.load_flags = 0;
9822
[email protected]bb88e1d32013-05-03 23:11:079823 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:079824 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:279825 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:079826 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:279827
[email protected]8e6441ca2010-08-19 05:56:389828 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9829 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079830 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:389831
[email protected]49639fa2011-12-20 23:22:419832 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:389833
[email protected]333bdf62012-06-08 22:57:299834 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:419835 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:389836 EXPECT_EQ(ERR_IO_PENDING, rv);
9837 trans.reset(); // Cancel the transaction here.
9838
[email protected]2da659e2013-05-23 20:51:349839 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:309840}
9841
[email protected]76a505b2010-08-25 06:23:009842// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029843TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:079844 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209845 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299846 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079847 session_deps_.net_log = log.bound().net_log();
9848 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009849
[email protected]76a505b2010-08-25 06:23:009850 HttpRequestInfo request;
9851 request.method = "GET";
9852 request.url = GURL("http://www.google.com/");
9853
9854 MockWrite data_writes1[] = {
9855 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9856 "Host: www.google.com\r\n"
9857 "Proxy-Connection: keep-alive\r\n\r\n"),
9858 };
9859
9860 MockRead data_reads1[] = {
9861 MockRead("HTTP/1.1 200 OK\r\n"),
9862 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9863 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069864 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009865 };
9866
9867 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9868 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:009870
[email protected]49639fa2011-12-20 23:22:419871 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009872
[email protected]262eec82013-03-19 21:01:369873 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509874 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509875
[email protected]49639fa2011-12-20 23:22:419876 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009877 EXPECT_EQ(ERR_IO_PENDING, rv);
9878
9879 rv = callback1.WaitForResult();
9880 EXPECT_EQ(OK, rv);
9881
9882 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509883 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009884
9885 EXPECT_TRUE(response->headers->IsKeepAlive());
9886 EXPECT_EQ(200, response->headers->response_code());
9887 EXPECT_EQ(100, response->headers->GetContentLength());
9888 EXPECT_TRUE(response->was_fetched_via_proxy);
9889 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209890
9891 LoadTimingInfo load_timing_info;
9892 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9893 TestLoadTimingNotReusedWithPac(load_timing_info,
9894 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:009895}
9896
9897// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029898TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:079899 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209900 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299901 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079902 session_deps_.net_log = log.bound().net_log();
9903 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009904
[email protected]76a505b2010-08-25 06:23:009905 HttpRequestInfo request;
9906 request.method = "GET";
9907 request.url = GURL("https://www.google.com/");
9908
9909 // Since we have proxy, should try to establish tunnel.
9910 MockWrite data_writes1[] = {
9911 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9912 "Host: www.google.com\r\n"
9913 "Proxy-Connection: keep-alive\r\n\r\n"),
9914
9915 MockWrite("GET / HTTP/1.1\r\n"
9916 "Host: www.google.com\r\n"
9917 "Connection: keep-alive\r\n\r\n"),
9918 };
9919
9920 MockRead data_reads1[] = {
9921 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
9922
9923 MockRead("HTTP/1.1 200 OK\r\n"),
9924 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9925 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069926 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009927 };
9928
9929 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9930 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069932 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009934
[email protected]49639fa2011-12-20 23:22:419935 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009936
[email protected]262eec82013-03-19 21:01:369937 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509939
[email protected]49639fa2011-12-20 23:22:419940 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009941 EXPECT_EQ(ERR_IO_PENDING, rv);
9942
9943 rv = callback1.WaitForResult();
9944 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:579945 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409946 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009947 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409948 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009949 NetLog::PHASE_NONE);
9950 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409951 entries, pos,
[email protected]76a505b2010-08-25 06:23:009952 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9953 NetLog::PHASE_NONE);
9954
9955 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509956 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009957
9958 EXPECT_TRUE(response->headers->IsKeepAlive());
9959 EXPECT_EQ(200, response->headers->response_code());
9960 EXPECT_EQ(100, response->headers->GetContentLength());
9961 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9962 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:209963
9964 LoadTimingInfo load_timing_info;
9965 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9966 TestLoadTimingNotReusedWithPac(load_timing_info,
9967 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:009968}
9969
9970// Test a basic HTTPS GET request through a proxy, but the server hangs up
9971// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:029972TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:079973 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299974 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079975 session_deps_.net_log = log.bound().net_log();
9976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009977
[email protected]76a505b2010-08-25 06:23:009978 HttpRequestInfo request;
9979 request.method = "GET";
9980 request.url = GURL("https://www.google.com/");
9981
9982 // Since we have proxy, should try to establish tunnel.
9983 MockWrite data_writes1[] = {
9984 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9985 "Host: www.google.com\r\n"
9986 "Proxy-Connection: keep-alive\r\n\r\n"),
9987
9988 MockWrite("GET / HTTP/1.1\r\n"
9989 "Host: www.google.com\r\n"
9990 "Connection: keep-alive\r\n\r\n"),
9991 };
9992
9993 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:069994 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:009995 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069996 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:009997 };
9998
9999 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10000 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710001 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610002 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710003 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010004
[email protected]49639fa2011-12-20 23:22:4110005 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010006
[email protected]262eec82013-03-19 21:01:3610007 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010009
[email protected]49639fa2011-12-20 23:22:4110010 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010011 EXPECT_EQ(ERR_IO_PENDING, rv);
10012
10013 rv = callback1.WaitForResult();
10014 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710015 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010016 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010017 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010018 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010019 NetLog::PHASE_NONE);
10020 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010021 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010022 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10023 NetLog::PHASE_NONE);
10024}
10025
[email protected]749eefa82010-09-13 22:14:0310026// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210027TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610028 scoped_ptr<SpdyFrame> req(
10029 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310030 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10031
[email protected]23e482282013-06-14 16:08:0210032 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10033 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310034 MockRead spdy_reads[] = {
10035 CreateMockRead(*resp),
10036 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610037 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310038 };
10039
[email protected]dd54bd82012-07-19 23:44:5710040 DelayedSocketData spdy_data(
10041 1, // wait for one write to finish before reading.
10042 spdy_reads, arraysize(spdy_reads),
10043 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710044 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310045
[email protected]8ddf8322012-02-23 18:08:0610046 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210047 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310049
[email protected]bb88e1d32013-05-03 23:11:0710050 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310051
10052 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810053 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010054 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10055 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:2710056 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610057 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310058
10059 HttpRequestInfo request;
10060 request.method = "GET";
10061 request.url = GURL("https://www.google.com/");
10062 request.load_flags = 0;
10063
10064 // This is the important line that marks this as a preconnect.
10065 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10066
[email protected]262eec82013-03-19 21:01:3610067 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010068 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310069
[email protected]41d64e82013-07-03 22:44:2610070 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110071 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310072 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110073 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310074}
10075
[email protected]73b8dd222010-11-11 19:55:2410076// Given a net error, cause that error to be returned from the first Write()
10077// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210078void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710079 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710080 net::HttpRequestInfo request_info;
10081 request_info.url = GURL("https://www.example.com/");
10082 request_info.method = "GET";
10083 request_info.load_flags = net::LOAD_NORMAL;
10084
[email protected]8ddf8322012-02-23 18:08:0610085 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410086 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610087 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410088 };
10089 net::StaticSocketDataProvider data(NULL, 0,
10090 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710091 session_deps_.socket_factory->AddSocketDataProvider(&data);
10092 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410093
[email protected]bb88e1d32013-05-03 23:11:0710094 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610095 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010096 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410097
[email protected]49639fa2011-12-20 23:22:4110098 TestCompletionCallback callback;
10099 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410100 if (rv == net::ERR_IO_PENDING)
10101 rv = callback.WaitForResult();
10102 ASSERT_EQ(error, rv);
10103}
10104
[email protected]23e482282013-06-14 16:08:0210105TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410106 // Just check a grab bag of cert errors.
10107 static const int kErrors[] = {
10108 ERR_CERT_COMMON_NAME_INVALID,
10109 ERR_CERT_AUTHORITY_INVALID,
10110 ERR_CERT_DATE_INVALID,
10111 };
10112 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610113 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10114 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410115 }
10116}
10117
[email protected]bd0b6772011-01-11 19:59:3010118// Ensure that a client certificate is removed from the SSL client auth
10119// cache when:
10120// 1) No proxy is involved.
10121// 2) TLS False Start is disabled.
10122// 3) The initial TLS handshake requests a client certificate.
10123// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210124TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310125 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710126 net::HttpRequestInfo request_info;
10127 request_info.url = GURL("https://www.example.com/");
10128 request_info.method = "GET";
10129 request_info.load_flags = net::LOAD_NORMAL;
10130
[email protected]bd0b6772011-01-11 19:59:3010131 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10132 cert_request->host_and_port = "www.example.com:443";
10133
10134 // [ssl_]data1 contains the data for the first SSL handshake. When a
10135 // CertificateRequest is received for the first time, the handshake will
10136 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610137 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010138 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010140 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710141 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010142
10143 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10144 // False Start is not being used, the result of the SSL handshake will be
10145 // returned as part of the SSLClientSocket::Connect() call. This test
10146 // matches the result of a server sending a handshake_failure alert,
10147 // rather than a Finished message, because it requires a client
10148 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610149 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010150 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010152 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710153 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010154
10155 // [ssl_]data3 contains the data for the third SSL handshake. When a
10156 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710157 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10158 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010159 // of the HttpNetworkTransaction. Because this test failure is due to
10160 // requiring a client certificate, this fallback handshake should also
10161 // fail.
[email protected]8ddf8322012-02-23 18:08:0610162 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010163 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010165 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710166 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010167
[email protected]80c75f682012-05-26 16:22:1710168 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10169 // connection to a server fails during an SSL handshake,
10170 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10171 // connection was attempted with TLSv1. This is transparent to the caller
10172 // of the HttpNetworkTransaction. Because this test failure is due to
10173 // requiring a client certificate, this fallback handshake should also
10174 // fail.
10175 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10176 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710178 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710179 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710180
[email protected]7799de12013-05-30 05:52:5110181 // Need one more if TLSv1.2 is enabled.
10182 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10183 ssl_data5.cert_request_info = cert_request.get();
10184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10185 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10186 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10187
[email protected]bb88e1d32013-05-03 23:11:0710188 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610189 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010190 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010191
[email protected]bd0b6772011-01-11 19:59:3010192 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110193 TestCompletionCallback callback;
10194 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010195 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10196
10197 // Complete the SSL handshake, which should abort due to requiring a
10198 // client certificate.
10199 rv = callback.WaitForResult();
10200 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10201
10202 // Indicate that no certificate should be supplied. From the perspective
10203 // of SSLClientCertCache, NULL is just as meaningful as a real
10204 // certificate, so this is the same as supply a
10205 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110206 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010207 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10208
10209 // Ensure the certificate was added to the client auth cache before
10210 // allowing the connection to continue restarting.
10211 scoped_refptr<X509Certificate> client_cert;
10212 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10213 &client_cert));
10214 ASSERT_EQ(NULL, client_cert.get());
10215
10216 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710217 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10218 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010219 rv = callback.WaitForResult();
10220 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10221
10222 // Ensure that the client certificate is removed from the cache on a
10223 // handshake failure.
10224 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10225 &client_cert));
10226}
10227
10228// Ensure that a client certificate is removed from the SSL client auth
10229// cache when:
10230// 1) No proxy is involved.
10231// 2) TLS False Start is enabled.
10232// 3) The initial TLS handshake requests a client certificate.
10233// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210234TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310235 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710236 net::HttpRequestInfo request_info;
10237 request_info.url = GURL("https://www.example.com/");
10238 request_info.method = "GET";
10239 request_info.load_flags = net::LOAD_NORMAL;
10240
[email protected]bd0b6772011-01-11 19:59:3010241 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10242 cert_request->host_and_port = "www.example.com:443";
10243
10244 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10245 // return successfully after reading up to the peer's Certificate message.
10246 // This is to allow the caller to call SSLClientSocket::Write(), which can
10247 // enqueue application data to be sent in the same packet as the
10248 // ChangeCipherSpec and Finished messages.
10249 // The actual handshake will be finished when SSLClientSocket::Read() is
10250 // called, which expects to process the peer's ChangeCipherSpec and
10251 // Finished messages. If there was an error negotiating with the peer,
10252 // such as due to the peer requiring a client certificate when none was
10253 // supplied, the alert sent by the peer won't be processed until Read() is
10254 // called.
10255
10256 // Like the non-False Start case, when a client certificate is requested by
10257 // the peer, the handshake is aborted during the Connect() call.
10258 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610259 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010260 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010262 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710263 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010264
10265 // When a client certificate is supplied, Connect() will not be aborted
10266 // when the peer requests the certificate. Instead, the handshake will
10267 // artificially succeed, allowing the caller to write the HTTP request to
10268 // the socket. The handshake messages are not processed until Read() is
10269 // called, which then detects that the handshake was aborted, due to the
10270 // peer sending a handshake_failure because it requires a client
10271 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610272 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010273 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010275 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610276 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010277 };
10278 net::StaticSocketDataProvider data2(
10279 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710280 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010281
10282 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710283 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10284 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610285 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010286 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710287 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010288 net::StaticSocketDataProvider data3(
10289 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710290 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010291
[email protected]80c75f682012-05-26 16:22:1710292 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10293 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10294 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10295 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710297 net::StaticSocketDataProvider data4(
10298 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710299 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710300
[email protected]7799de12013-05-30 05:52:5110301 // Need one more if TLSv1.2 is enabled.
10302 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10303 ssl_data5.cert_request_info = cert_request.get();
10304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10305 net::StaticSocketDataProvider data5(
10306 data2_reads, arraysize(data2_reads), NULL, 0);
10307 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10308
[email protected]bb88e1d32013-05-03 23:11:0710309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010312
[email protected]bd0b6772011-01-11 19:59:3010313 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110314 TestCompletionCallback callback;
10315 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010316 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10317
10318 // Complete the SSL handshake, which should abort due to requiring a
10319 // client certificate.
10320 rv = callback.WaitForResult();
10321 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10322
10323 // Indicate that no certificate should be supplied. From the perspective
10324 // of SSLClientCertCache, NULL is just as meaningful as a real
10325 // certificate, so this is the same as supply a
10326 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110327 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010328 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10329
10330 // Ensure the certificate was added to the client auth cache before
10331 // allowing the connection to continue restarting.
10332 scoped_refptr<X509Certificate> client_cert;
10333 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10334 &client_cert));
10335 ASSERT_EQ(NULL, client_cert.get());
10336
[email protected]bd0b6772011-01-11 19:59:3010337 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710338 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10339 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010340 rv = callback.WaitForResult();
10341 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10342
10343 // Ensure that the client certificate is removed from the cache on a
10344 // handshake failure.
10345 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10346 &client_cert));
10347}
10348
[email protected]8c405132011-01-11 22:03:1810349// Ensure that a client certificate is removed from the SSL client auth
10350// cache when:
10351// 1) An HTTPS proxy is involved.
10352// 3) The HTTPS proxy requests a client certificate.
10353// 4) The client supplies an invalid/unacceptable certificate for the
10354// proxy.
10355// The test is repeated twice, first for connecting to an HTTPS endpoint,
10356// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210357TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710358 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810359 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910360 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710361 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810362
10363 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10364 cert_request->host_and_port = "proxy:70";
10365
10366 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10367 // [ssl_]data[1-3]. Rather than represending the endpoint
10368 // (www.example.com:443), they represent failures with the HTTPS proxy
10369 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610370 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810371 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810373 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710374 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810375
[email protected]8ddf8322012-02-23 18:08:0610376 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810377 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810379 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710380 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810381
[email protected]80c75f682012-05-26 16:22:1710382 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10383#if 0
[email protected]8ddf8322012-02-23 18:08:0610384 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810385 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810387 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710388 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710389#endif
[email protected]8c405132011-01-11 22:03:1810390
10391 net::HttpRequestInfo requests[2];
10392 requests[0].url = GURL("https://www.example.com/");
10393 requests[0].method = "GET";
10394 requests[0].load_flags = net::LOAD_NORMAL;
10395
10396 requests[1].url = GURL("http://www.example.com/");
10397 requests[1].method = "GET";
10398 requests[1].load_flags = net::LOAD_NORMAL;
10399
10400 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710401 session_deps_.socket_factory->ResetNextMockIndexes();
10402 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810403 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810405
10406 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110407 TestCompletionCallback callback;
10408 int rv = trans->Start(
10409 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810410 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10411
10412 // Complete the SSL handshake, which should abort due to requiring a
10413 // client certificate.
10414 rv = callback.WaitForResult();
10415 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10416
10417 // Indicate that no certificate should be supplied. From the perspective
10418 // of SSLClientCertCache, NULL is just as meaningful as a real
10419 // certificate, so this is the same as supply a
10420 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110421 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810422 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10423
10424 // Ensure the certificate was added to the client auth cache before
10425 // allowing the connection to continue restarting.
10426 scoped_refptr<X509Certificate> client_cert;
10427 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10428 &client_cert));
10429 ASSERT_EQ(NULL, client_cert.get());
10430 // Ensure the certificate was NOT cached for the endpoint. This only
10431 // applies to HTTPS requests, but is fine to check for HTTP requests.
10432 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10433 &client_cert));
10434
10435 // Restart the handshake. This will consume ssl_data2, which fails, and
10436 // then consume ssl_data3, which should also fail. The result code is
10437 // checked against what ssl_data3 should return.
10438 rv = callback.WaitForResult();
10439 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10440
10441 // Now that the new handshake has failed, ensure that the client
10442 // certificate was removed from the client auth cache.
10443 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10444 &client_cert));
10445 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10446 &client_cert));
10447 }
10448}
10449
[email protected]23e482282013-06-14 16:08:0210450// Unlike TEST/TEST_F, which are macros that expand to further macros,
10451// TEST_P is a macro that expands directly to code that stringizes the
10452// arguments. As a result, macros passed as parameters (such as prefix
10453// or test_case_name) will not be expanded by the preprocessor. To
10454// work around this, indirect the macro for TEST_P, so that the
10455// pre-processor will expand macros such as MAYBE_test_name before
10456// instantiating the test.
10457#define WRAPPED_TEST_P(test_case_name, test_name) \
10458 TEST_P(test_case_name, test_name)
10459
[email protected]45b170822012-05-04 21:18:1410460// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10461#if defined(OS_WIN)
10462#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10463#else
10464#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10465#endif
[email protected]23e482282013-06-14 16:08:0210466WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610467 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310468 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610469
10470 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710471 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10472 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610473 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10474 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610475
[email protected]8ddf8322012-02-23 18:08:0610476 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210477 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610479
[email protected]cdf8f7e72013-05-23 10:56:4610480 scoped_ptr<SpdyFrame> host1_req(
10481 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10482 scoped_ptr<SpdyFrame> host2_req(
10483 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610484 MockWrite spdy_writes[] = {
10485 CreateMockWrite(*host1_req, 1),
10486 CreateMockWrite(*host2_req, 4),
10487 };
[email protected]23e482282013-06-14 16:08:0210488 scoped_ptr<SpdyFrame> host1_resp(
10489 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10490 scoped_ptr<SpdyFrame> host1_resp_body(
10491 spdy_util_.ConstructSpdyBodyFrame(1, true));
10492 scoped_ptr<SpdyFrame> host2_resp(
10493 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10494 scoped_ptr<SpdyFrame> host2_resp_body(
10495 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610496 MockRead spdy_reads[] = {
10497 CreateMockRead(*host1_resp, 2),
10498 CreateMockRead(*host1_resp_body, 3),
10499 CreateMockRead(*host2_resp, 5),
10500 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610501 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610502 };
10503
[email protected]d2b5f092012-06-08 23:55:0210504 IPAddressNumber ip;
10505 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10506 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10507 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710508 OrderedSocketData spdy_data(
10509 connect,
10510 spdy_reads, arraysize(spdy_reads),
10511 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710512 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610513
[email protected]aa22b242011-11-16 18:58:2910514 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610515 HttpRequestInfo request1;
10516 request1.method = "GET";
10517 request1.url = GURL("https://www.google.com/");
10518 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010519 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610520
[email protected]49639fa2011-12-20 23:22:4110521 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610522 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110523 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610524
10525 const HttpResponseInfo* response = trans1.GetResponseInfo();
10526 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010527 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610528 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10529
10530 std::string response_data;
10531 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10532 EXPECT_EQ("hello!", response_data);
10533
10534 // Preload www.gmail.com into HostCache.
10535 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010536 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610537 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010538 rv = session_deps_.host_resolver->Resolve(resolve_info,
10539 DEFAULT_PRIORITY,
10540 &ignored,
10541 callback.callback(),
10542 NULL,
10543 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710544 EXPECT_EQ(ERR_IO_PENDING, rv);
10545 rv = callback.WaitForResult();
10546 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610547
10548 HttpRequestInfo request2;
10549 request2.method = "GET";
10550 request2.url = GURL("https://www.gmail.com/");
10551 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010552 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610553
[email protected]49639fa2011-12-20 23:22:4110554 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610555 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110556 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610557
10558 response = trans2.GetResponseInfo();
10559 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010560 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610561 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10562 EXPECT_TRUE(response->was_fetched_via_spdy);
10563 EXPECT_TRUE(response->was_npn_negotiated);
10564 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10565 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610566}
[email protected]45b170822012-05-04 21:18:1410567#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610568
[email protected]23e482282013-06-14 16:08:0210569TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210570 HttpStreamFactory::set_use_alternate_protocols(true);
10571 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10572
10573 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710574 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10575 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210576 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10577 pool_peer.DisableDomainAuthenticationVerification();
10578
10579 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210580 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710581 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210582
[email protected]cdf8f7e72013-05-23 10:56:4610583 scoped_ptr<SpdyFrame> host1_req(
10584 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10585 scoped_ptr<SpdyFrame> host2_req(
10586 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210587 MockWrite spdy_writes[] = {
10588 CreateMockWrite(*host1_req, 1),
10589 CreateMockWrite(*host2_req, 4),
10590 };
[email protected]23e482282013-06-14 16:08:0210591 scoped_ptr<SpdyFrame> host1_resp(
10592 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10593 scoped_ptr<SpdyFrame> host1_resp_body(
10594 spdy_util_.ConstructSpdyBodyFrame(1, true));
10595 scoped_ptr<SpdyFrame> host2_resp(
10596 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10597 scoped_ptr<SpdyFrame> host2_resp_body(
10598 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210599 MockRead spdy_reads[] = {
10600 CreateMockRead(*host1_resp, 2),
10601 CreateMockRead(*host1_resp_body, 3),
10602 CreateMockRead(*host2_resp, 5),
10603 CreateMockRead(*host2_resp_body, 6),
10604 MockRead(ASYNC, 0, 7),
10605 };
10606
10607 IPAddressNumber ip;
10608 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10609 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10610 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710611 OrderedSocketData spdy_data(
10612 connect,
10613 spdy_reads, arraysize(spdy_reads),
10614 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710615 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210616
10617 TestCompletionCallback callback;
10618 HttpRequestInfo request1;
10619 request1.method = "GET";
10620 request1.url = GURL("https://www.google.com/");
10621 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010622 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210623
10624 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10625 EXPECT_EQ(ERR_IO_PENDING, rv);
10626 EXPECT_EQ(OK, callback.WaitForResult());
10627
10628 const HttpResponseInfo* response = trans1.GetResponseInfo();
10629 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010630 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210631 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10632
10633 std::string response_data;
10634 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10635 EXPECT_EQ("hello!", response_data);
10636
10637 HttpRequestInfo request2;
10638 request2.method = "GET";
10639 request2.url = GURL("https://www.gmail.com/");
10640 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010641 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210642
10643 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10644 EXPECT_EQ(ERR_IO_PENDING, rv);
10645 EXPECT_EQ(OK, callback.WaitForResult());
10646
10647 response = trans2.GetResponseInfo();
10648 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010649 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210650 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10651 EXPECT_TRUE(response->was_fetched_via_spdy);
10652 EXPECT_TRUE(response->was_npn_negotiated);
10653 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10654 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210655}
10656
[email protected]e3ceb682011-06-28 23:55:4610657class OneTimeCachingHostResolver : public net::HostResolver {
10658 public:
10659 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10660 : host_port_(host_port) {}
10661 virtual ~OneTimeCachingHostResolver() {}
10662
10663 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10664
10665 // HostResolver methods:
10666 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010667 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610668 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910669 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610670 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010671 const BoundNetLog& net_log) OVERRIDE {
10672 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010673 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010674 }
10675
10676 virtual int ResolveFromCache(const RequestInfo& info,
10677 AddressList* addresses,
10678 const BoundNetLog& net_log) OVERRIDE {
10679 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10680 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910681 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610682 return rv;
10683 }
10684
[email protected]95a214c2011-08-04 21:50:4010685 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610686 host_resolver_.CancelRequest(req);
10687 }
10688
[email protected]46da33be2011-07-19 21:58:0410689 MockCachingHostResolver* GetMockHostResolver() {
10690 return &host_resolver_;
10691 }
10692
[email protected]e3ceb682011-06-28 23:55:4610693 private:
10694 MockCachingHostResolver host_resolver_;
10695 const HostPortPair host_port_;
10696};
10697
[email protected]45b170822012-05-04 21:18:1410698// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10699#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710700#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10701 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410702#else
[email protected]bb88e1d32013-05-03 23:11:0710703#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10704 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410705#endif
[email protected]23e482282013-06-14 16:08:0210706WRAPPED_TEST_P(HttpNetworkTransactionTest,
10707 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210708// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10709// prefix doesn't work with parametrized tests).
10710#if defined(OS_WIN)
10711 return;
10712#endif
10713
[email protected]e3ceb682011-06-28 23:55:4610714 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310715 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610716
10717 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610718 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410719 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710720 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610721 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710722 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610723 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10724 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610725
[email protected]8ddf8322012-02-23 18:08:0610726 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210727 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610729
[email protected]cdf8f7e72013-05-23 10:56:4610730 scoped_ptr<SpdyFrame> host1_req(
10731 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10732 scoped_ptr<SpdyFrame> host2_req(
10733 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610734 MockWrite spdy_writes[] = {
10735 CreateMockWrite(*host1_req, 1),
10736 CreateMockWrite(*host2_req, 4),
10737 };
[email protected]23e482282013-06-14 16:08:0210738 scoped_ptr<SpdyFrame> host1_resp(
10739 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10740 scoped_ptr<SpdyFrame> host1_resp_body(
10741 spdy_util_.ConstructSpdyBodyFrame(1, true));
10742 scoped_ptr<SpdyFrame> host2_resp(
10743 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10744 scoped_ptr<SpdyFrame> host2_resp_body(
10745 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610746 MockRead spdy_reads[] = {
10747 CreateMockRead(*host1_resp, 2),
10748 CreateMockRead(*host1_resp_body, 3),
10749 CreateMockRead(*host2_resp, 5),
10750 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610751 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610752 };
10753
[email protected]d2b5f092012-06-08 23:55:0210754 IPAddressNumber ip;
10755 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10756 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10757 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710758 OrderedSocketData spdy_data(
10759 connect,
10760 spdy_reads, arraysize(spdy_reads),
10761 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710762 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610763
[email protected]aa22b242011-11-16 18:58:2910764 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610765 HttpRequestInfo request1;
10766 request1.method = "GET";
10767 request1.url = GURL("https://www.google.com/");
10768 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010769 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610770
[email protected]49639fa2011-12-20 23:22:4110771 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610772 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110773 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610774
10775 const HttpResponseInfo* response = trans1.GetResponseInfo();
10776 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010777 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610778 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10779
10780 std::string response_data;
10781 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10782 EXPECT_EQ("hello!", response_data);
10783
10784 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1010785 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4610786 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010787 rv = host_resolver.Resolve(resolve_info,
10788 DEFAULT_PRIORITY,
10789 &ignored,
10790 callback.callback(),
10791 NULL,
10792 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710793 EXPECT_EQ(ERR_IO_PENDING, rv);
10794 rv = callback.WaitForResult();
10795 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610796
10797 HttpRequestInfo request2;
10798 request2.method = "GET";
10799 request2.url = GURL("https://www.gmail.com/");
10800 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010801 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610802
[email protected]49639fa2011-12-20 23:22:4110803 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610804 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110805 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610806
10807 response = trans2.GetResponseInfo();
10808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010809 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10811 EXPECT_TRUE(response->was_fetched_via_spdy);
10812 EXPECT_TRUE(response->was_npn_negotiated);
10813 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10814 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610815}
[email protected]45b170822012-05-04 21:18:1410816#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4610817
[email protected]23e482282013-06-14 16:08:0210818TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910819 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610820 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910821 };
10822 MockRead data_reads2[] = {
10823 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10824 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610825 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910826 };
10827 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10828 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10829 StaticSocketDataProvider* data[] = { &data1, &data2 };
10830
10831 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10832
10833 EXPECT_EQ(OK, out.rv);
10834 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10835 EXPECT_EQ("hello world", out.response_data);
10836}
10837
[email protected]23e482282013-06-14 16:08:0210838TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910839 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0610840 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910841 };
10842 MockWrite data_writes2[] = {
10843 MockWrite("GET / HTTP/1.1\r\n"
10844 "Host: www.google.com\r\n"
10845 "Connection: keep-alive\r\n\r\n"),
10846 };
10847 MockRead data_reads2[] = {
10848 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10849 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610850 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910851 };
10852 StaticSocketDataProvider data1(NULL, 0,
10853 data_writes1, arraysize(data_writes1));
10854 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10855 data_writes2, arraysize(data_writes2));
10856 StaticSocketDataProvider* data[] = { &data1, &data2 };
10857
10858 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10859
10860 EXPECT_EQ(OK, out.rv);
10861 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10862 EXPECT_EQ("hello world", out.response_data);
10863}
10864
[email protected]23e482282013-06-14 16:08:0210865TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0410866 const std::string https_url = "https://www.google.com/";
10867 const std::string http_url = "http://www.google.com:443/";
10868
10869 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4610870 scoped_ptr<SpdyFrame> req1(
10871 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410872
10873 MockWrite writes1[] = {
10874 CreateMockWrite(*req1, 0),
10875 };
10876
[email protected]23e482282013-06-14 16:08:0210877 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10878 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0410879 MockRead reads1[] = {
10880 CreateMockRead(*resp1, 1),
10881 CreateMockRead(*body1, 2),
10882 MockRead(ASYNC, ERR_IO_PENDING, 3)
10883 };
10884
[email protected]dd54bd82012-07-19 23:44:5710885 DelayedSocketData data1(
10886 1, reads1, arraysize(reads1),
10887 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410888 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710889 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410890
10891 // HTTP GET for the HTTP URL
10892 MockWrite writes2[] = {
10893 MockWrite(ASYNC, 4,
10894 "GET / HTTP/1.1\r\n"
10895 "Host: www.google.com:443\r\n"
10896 "Connection: keep-alive\r\n\r\n"),
10897 };
10898
10899 MockRead reads2[] = {
10900 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10901 MockRead(ASYNC, 6, "hello"),
10902 MockRead(ASYNC, 7, OK),
10903 };
10904
[email protected]dd54bd82012-07-19 23:44:5710905 DelayedSocketData data2(
10906 1, reads2, arraysize(reads2),
10907 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0410908
[email protected]8450d722012-07-02 19:14:0410909 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210910 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710911 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10912 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10913 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0410914
[email protected]bb88e1d32013-05-03 23:11:0710915 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410916
10917 // Start the first transaction to set up the SpdySession
10918 HttpRequestInfo request1;
10919 request1.method = "GET";
10920 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410921 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010922 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410923 TestCompletionCallback callback1;
10924 EXPECT_EQ(ERR_IO_PENDING,
10925 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410926 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410927
10928 EXPECT_EQ(OK, callback1.WaitForResult());
10929 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
10930
10931 // Now, start the HTTP request
10932 HttpRequestInfo request2;
10933 request2.method = "GET";
10934 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0410935 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010936 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0410937 TestCompletionCallback callback2;
10938 EXPECT_EQ(ERR_IO_PENDING,
10939 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410940 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410941
10942 EXPECT_EQ(OK, callback2.WaitForResult());
10943 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
10944}
10945
[email protected]23e482282013-06-14 16:08:0210946TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0410947 const std::string https_url = "https://www.google.com/";
10948 const std::string http_url = "http://www.google.com:443/";
10949
10950 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5410951 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
10952 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4610953 scoped_ptr<SpdyFrame> req1(
10954 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410955
10956 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0210957 scoped_ptr<SpdyFrame> wrapped_req1(
10958 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0410959 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0210960 spdy_util_.GetMethodKey(), "GET",
10961 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
10962 spdy_util_.GetHostKey(), "www.google.com:443",
10963 spdy_util_.GetSchemeKey(), "http",
10964 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0410965 };
[email protected]4bd46222013-05-14 19:32:2310966 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
10967 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
10968 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0410969
10970 MockWrite writes1[] = {
10971 CreateMockWrite(*connect, 0),
10972 CreateMockWrite(*wrapped_req1, 2),
10973 CreateMockWrite(*req2, 5),
10974 };
10975
[email protected]23e482282013-06-14 16:08:0210976 scoped_ptr<SpdyFrame> conn_resp(
10977 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10978 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10979 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10980 scoped_ptr<SpdyFrame> wrapped_resp1(
10981 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
10982 scoped_ptr<SpdyFrame> wrapped_body1(
10983 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
10984 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10985 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0410986 MockRead reads1[] = {
10987 CreateMockRead(*conn_resp, 1),
10988 CreateMockRead(*wrapped_resp1, 3),
10989 CreateMockRead(*wrapped_body1, 4),
10990 CreateMockRead(*resp2, 6),
10991 CreateMockRead(*body2, 7),
10992 MockRead(ASYNC, ERR_IO_PENDING, 8)
10993 };
10994
[email protected]dd54bd82012-07-19 23:44:5710995 DeterministicSocketData data1(reads1, arraysize(reads1),
10996 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410997 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710998 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410999
[email protected]bb88e1d32013-05-03 23:11:0711000 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211001 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11002 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711003 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411004 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211005 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711006 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411007 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211008 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711009 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11010 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411011
11012 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711013 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411014
11015 // Start the first transaction to set up the SpdySession
11016 HttpRequestInfo request1;
11017 request1.method = "GET";
11018 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411019 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011020 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411021 TestCompletionCallback callback1;
11022 EXPECT_EQ(ERR_IO_PENDING,
11023 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411024 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711025 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411026
11027 EXPECT_EQ(OK, callback1.WaitForResult());
11028 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11029
[email protected]f6c63db52013-02-02 00:35:2211030 LoadTimingInfo load_timing_info1;
11031 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11032 TestLoadTimingNotReusedWithPac(load_timing_info1,
11033 CONNECT_TIMING_HAS_SSL_TIMES);
11034
[email protected]8450d722012-07-02 19:14:0411035 // Now, start the HTTP request
11036 HttpRequestInfo request2;
11037 request2.method = "GET";
11038 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411039 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011040 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411041 TestCompletionCallback callback2;
11042 EXPECT_EQ(ERR_IO_PENDING,
11043 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411044 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711045 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411046
11047 EXPECT_EQ(OK, callback2.WaitForResult());
11048 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211049
11050 LoadTimingInfo load_timing_info2;
11051 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11052 // The established SPDY sessions is considered reused by the HTTP request.
11053 TestLoadTimingReusedWithPac(load_timing_info2);
11054 // HTTP requests over a SPDY session should have a different connection
11055 // socket_log_id than requests over a tunnel.
11056 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411057}
11058
[email protected]23e482282013-06-14 16:08:0211059TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411060 HttpStreamFactory::set_force_spdy_always(true);
11061 const std::string https_url = "https://www.google.com/";
11062 const std::string http_url = "http://www.google.com:443/";
11063
11064 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611065 scoped_ptr<SpdyFrame> req1(
11066 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411067 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611068 scoped_ptr<SpdyFrame> req2(
11069 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411070
11071 MockWrite writes[] = {
11072 CreateMockWrite(*req1, 1),
11073 CreateMockWrite(*req2, 4),
11074 };
11075
[email protected]23e482282013-06-14 16:08:0211076 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11077 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11078 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11079 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411080 MockRead reads[] = {
11081 CreateMockRead(*resp1, 2),
11082 CreateMockRead(*body1, 3),
11083 CreateMockRead(*resp2, 5),
11084 CreateMockRead(*body2, 6),
11085 MockRead(ASYNC, ERR_IO_PENDING, 7)
11086 };
11087
[email protected]dd54bd82012-07-19 23:44:5711088 OrderedSocketData data(reads, arraysize(reads),
11089 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411090
[email protected]8450d722012-07-02 19:14:0411091 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211092 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11094 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411095
[email protected]bb88e1d32013-05-03 23:11:0711096 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411097
11098 // Start the first transaction to set up the SpdySession
11099 HttpRequestInfo request1;
11100 request1.method = "GET";
11101 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411102 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011103 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411104 TestCompletionCallback callback1;
11105 EXPECT_EQ(ERR_IO_PENDING,
11106 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411107 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411108
11109 EXPECT_EQ(OK, callback1.WaitForResult());
11110 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11111
11112 // Now, start the HTTP request
11113 HttpRequestInfo request2;
11114 request2.method = "GET";
11115 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411116 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011117 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411118 TestCompletionCallback callback2;
11119 EXPECT_EQ(ERR_IO_PENDING,
11120 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411121 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411122
11123 EXPECT_EQ(OK, callback2.WaitForResult());
11124 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11125}
11126
[email protected]2d88e7d2012-07-19 17:55:1711127// Test that in the case where we have a SPDY session to a SPDY proxy
11128// that we do not pool other origins that resolve to the same IP when
11129// the certificate does not match the new origin.
11130// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211131TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711132 const std::string url1 = "http://www.google.com/";
11133 const std::string url2 = "https://mail.google.com/";
11134 const std::string ip_addr = "1.2.3.4";
11135
11136 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211137 scoped_ptr<SpdyHeaderBlock> headers(
11138 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311139 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211140 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711141
11142 MockWrite writes1[] = {
11143 CreateMockWrite(*req1, 0),
11144 };
11145
[email protected]23e482282013-06-14 16:08:0211146 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11147 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711148 MockRead reads1[] = {
11149 CreateMockRead(*resp1, 1),
11150 CreateMockRead(*body1, 2),
11151 MockRead(ASYNC, OK, 3) // EOF
11152 };
11153
11154 scoped_ptr<DeterministicSocketData> data1(
11155 new DeterministicSocketData(reads1, arraysize(reads1),
11156 writes1, arraysize(writes1)));
11157 IPAddressNumber ip;
11158 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11159 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11160 MockConnect connect_data1(ASYNC, OK, peer_addr);
11161 data1->set_connect_data(connect_data1);
11162
11163 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611164 scoped_ptr<SpdyFrame> req2(
11165 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711166
11167 MockWrite writes2[] = {
11168 CreateMockWrite(*req2, 0),
11169 };
11170
[email protected]23e482282013-06-14 16:08:0211171 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11172 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711173 MockRead reads2[] = {
11174 CreateMockRead(*resp2, 1),
11175 CreateMockRead(*body2, 2),
11176 MockRead(ASYNC, OK, 3) // EOF
11177 };
11178
11179 scoped_ptr<DeterministicSocketData> data2(
11180 new DeterministicSocketData(reads2, arraysize(reads2),
11181 writes2, arraysize(writes2)));
11182 MockConnect connect_data2(ASYNC, OK);
11183 data2->set_connect_data(connect_data2);
11184
11185 // Set up a proxy config that sends HTTP requests to a proxy, and
11186 // all others direct.
11187 ProxyConfig proxy_config;
11188 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11189 CapturingProxyResolver* capturing_proxy_resolver =
11190 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711191 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711192 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11193 NULL));
11194
11195 // Load a valid cert. Note, that this does not need to
11196 // be valid for proxy because the MockSSLClientSocket does
11197 // not actually verify it. But SpdySession will use this
11198 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511199 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711200 scoped_refptr<X509Certificate> server_cert(
11201 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11202 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11203
11204 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211205 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711206 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711207 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11208 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11209 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711210
11211 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211212 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711213 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11214 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11215 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711216
[email protected]bb88e1d32013-05-03 23:11:0711217 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11218 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11219 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711220
11221 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711222 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711223
11224 // Start the first transaction to set up the SpdySession
11225 HttpRequestInfo request1;
11226 request1.method = "GET";
11227 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711228 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011229 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711230 TestCompletionCallback callback1;
11231 ASSERT_EQ(ERR_IO_PENDING,
11232 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11233 data1->RunFor(3);
11234
11235 ASSERT_TRUE(callback1.have_result());
11236 EXPECT_EQ(OK, callback1.WaitForResult());
11237 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11238
11239 // Now, start the HTTP request
11240 HttpRequestInfo request2;
11241 request2.method = "GET";
11242 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711243 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011244 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711245 TestCompletionCallback callback2;
11246 EXPECT_EQ(ERR_IO_PENDING,
11247 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411248 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711249 data2->RunFor(3);
11250
11251 ASSERT_TRUE(callback2.have_result());
11252 EXPECT_EQ(OK, callback2.WaitForResult());
11253 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11254}
11255
[email protected]85f97342013-04-17 06:12:2411256// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11257// error) in SPDY session, removes the socket from pool and closes the SPDY
11258// session. Verify that new url's from the same HttpNetworkSession (and a new
11259// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211260TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411261 const std::string https_url = "https://www.google.com/";
11262
11263 MockRead reads1[] = {
11264 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11265 };
11266
11267 scoped_ptr<DeterministicSocketData> data1(
11268 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11269 data1->SetStop(1);
11270
[email protected]cdf8f7e72013-05-23 10:56:4611271 scoped_ptr<SpdyFrame> req2(
11272 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411273 MockWrite writes2[] = {
11274 CreateMockWrite(*req2, 0),
11275 };
11276
[email protected]23e482282013-06-14 16:08:0211277 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11278 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411279 MockRead reads2[] = {
11280 CreateMockRead(*resp2, 1),
11281 CreateMockRead(*body2, 2),
11282 MockRead(ASYNC, OK, 3) // EOF
11283 };
11284
11285 scoped_ptr<DeterministicSocketData> data2(
11286 new DeterministicSocketData(reads2, arraysize(reads2),
11287 writes2, arraysize(writes2)));
11288
[email protected]85f97342013-04-17 06:12:2411289 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211290 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711291 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11292 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11293 data1.get());
[email protected]85f97342013-04-17 06:12:2411294
11295 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211296 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711297 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11298 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11299 data2.get());
[email protected]85f97342013-04-17 06:12:2411300
11301 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711302 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411303
11304 // Start the first transaction to set up the SpdySession and verify that
11305 // connection was closed.
11306 HttpRequestInfo request1;
11307 request1.method = "GET";
11308 request1.url = GURL(https_url);
11309 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011310 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411311 TestCompletionCallback callback1;
11312 EXPECT_EQ(ERR_IO_PENDING,
11313 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411314 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411315 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11316
11317 // Now, start the second request and make sure it succeeds.
11318 HttpRequestInfo request2;
11319 request2.method = "GET";
11320 request2.url = GURL(https_url);
11321 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011322 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411323 TestCompletionCallback callback2;
11324 EXPECT_EQ(ERR_IO_PENDING,
11325 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411326 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411327 data2->RunFor(3);
11328
11329 ASSERT_TRUE(callback2.have_result());
11330 EXPECT_EQ(OK, callback2.WaitForResult());
11331 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11332}
11333
[email protected]23e482282013-06-14 16:08:0211334TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311335 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11336 ClientSocketPoolManager::set_max_sockets_per_group(
11337 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11338 ClientSocketPoolManager::set_max_sockets_per_pool(
11339 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11340
11341 // Use two different hosts with different IPs so they don't get pooled.
11342 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11343 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11345
11346 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211347 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311348 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211349 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311350 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11352
[email protected]cdf8f7e72013-05-23 10:56:4611353 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311354 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11355 MockWrite spdy1_writes[] = {
11356 CreateMockWrite(*host1_req, 1),
11357 };
[email protected]23e482282013-06-14 16:08:0211358 scoped_ptr<SpdyFrame> host1_resp(
11359 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11360 scoped_ptr<SpdyFrame> host1_resp_body(
11361 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311362 MockRead spdy1_reads[] = {
11363 CreateMockRead(*host1_resp, 2),
11364 CreateMockRead(*host1_resp_body, 3),
11365 MockRead(ASYNC, ERR_IO_PENDING, 4),
11366 };
11367
11368 scoped_ptr<OrderedSocketData> spdy1_data(
11369 new OrderedSocketData(
11370 spdy1_reads, arraysize(spdy1_reads),
11371 spdy1_writes, arraysize(spdy1_writes)));
11372 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11373
[email protected]cdf8f7e72013-05-23 10:56:4611374 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311375 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11376 MockWrite spdy2_writes[] = {
11377 CreateMockWrite(*host2_req, 1),
11378 };
[email protected]23e482282013-06-14 16:08:0211379 scoped_ptr<SpdyFrame> host2_resp(
11380 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11381 scoped_ptr<SpdyFrame> host2_resp_body(
11382 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311383 MockRead spdy2_reads[] = {
11384 CreateMockRead(*host2_resp, 2),
11385 CreateMockRead(*host2_resp_body, 3),
11386 MockRead(ASYNC, ERR_IO_PENDING, 4),
11387 };
11388
11389 scoped_ptr<OrderedSocketData> spdy2_data(
11390 new OrderedSocketData(
11391 spdy2_reads, arraysize(spdy2_reads),
11392 spdy2_writes, arraysize(spdy2_writes)));
11393 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11394
11395 MockWrite http_write[] = {
11396 MockWrite("GET / HTTP/1.1\r\n"
11397 "Host: www.a.com\r\n"
11398 "Connection: keep-alive\r\n\r\n"),
11399 };
11400
11401 MockRead http_read[] = {
11402 MockRead("HTTP/1.1 200 OK\r\n"),
11403 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11404 MockRead("Content-Length: 6\r\n\r\n"),
11405 MockRead("hello!"),
11406 };
11407 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11408 http_write, arraysize(http_write));
11409 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11410
11411 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011412 SpdySessionKey spdy_session_key_a(
11413 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311414 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611415 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311416
11417 TestCompletionCallback callback;
11418 HttpRequestInfo request1;
11419 request1.method = "GET";
11420 request1.url = GURL("https://www.a.com/");
11421 request1.load_flags = 0;
11422 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311424
11425 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11426 EXPECT_EQ(ERR_IO_PENDING, rv);
11427 EXPECT_EQ(OK, callback.WaitForResult());
11428
11429 const HttpResponseInfo* response = trans->GetResponseInfo();
11430 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011431 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311432 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11433 EXPECT_TRUE(response->was_fetched_via_spdy);
11434 EXPECT_TRUE(response->was_npn_negotiated);
11435
11436 std::string response_data;
11437 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11438 EXPECT_EQ("hello!", response_data);
11439 trans.reset();
11440 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611441 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311442
11443 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011444 SpdySessionKey spdy_session_key_b(
11445 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311446 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611447 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311448 HttpRequestInfo request2;
11449 request2.method = "GET";
11450 request2.url = GURL("https://www.b.com/");
11451 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011452 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311453
11454 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11455 EXPECT_EQ(ERR_IO_PENDING, rv);
11456 EXPECT_EQ(OK, callback.WaitForResult());
11457
11458 response = trans->GetResponseInfo();
11459 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011460 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311461 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11462 EXPECT_TRUE(response->was_fetched_via_spdy);
11463 EXPECT_TRUE(response->was_npn_negotiated);
11464 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11465 EXPECT_EQ("hello!", response_data);
11466 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611467 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311468 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611469 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311470
11471 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011472 SpdySessionKey spdy_session_key_a1(
11473 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311474 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611475 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311476 HttpRequestInfo request3;
11477 request3.method = "GET";
11478 request3.url = GURL("http://www.a.com/");
11479 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011480 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311481
11482 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11483 EXPECT_EQ(ERR_IO_PENDING, rv);
11484 EXPECT_EQ(OK, callback.WaitForResult());
11485
11486 response = trans->GetResponseInfo();
11487 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011488 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311489 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11490 EXPECT_FALSE(response->was_fetched_via_spdy);
11491 EXPECT_FALSE(response->was_npn_negotiated);
11492 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11493 EXPECT_EQ("hello!", response_data);
11494 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611495 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311496 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611497 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311498}
11499
[email protected]79e1fd62013-06-20 06:50:0411500TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11501 HttpRequestInfo request;
11502 request.method = "GET";
11503 request.url = GURL("http://www.google.com/");
11504 request.load_flags = 0;
11505
[email protected]3fe8d2f82013-10-17 08:56:0711506 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411507 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711508 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411509
11510 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11511 StaticSocketDataProvider data;
11512 data.set_connect_data(mock_connect);
11513 session_deps_.socket_factory->AddSocketDataProvider(&data);
11514
11515 TestCompletionCallback callback;
11516
11517 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11518 EXPECT_EQ(ERR_IO_PENDING, rv);
11519
11520 rv = callback.WaitForResult();
11521 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11522
11523 EXPECT_EQ(NULL, trans->GetResponseInfo());
11524
11525 // We don't care whether this succeeds or fails, but it shouldn't crash.
11526 HttpRequestHeaders request_headers;
11527 trans->GetFullRequestHeaders(&request_headers);
11528}
11529
11530TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11531 HttpRequestInfo request;
11532 request.method = "GET";
11533 request.url = GURL("http://www.google.com/");
11534 request.load_flags = 0;
11535
[email protected]3fe8d2f82013-10-17 08:56:0711536 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411537 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711538 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411539
11540 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11541 StaticSocketDataProvider data;
11542 data.set_connect_data(mock_connect);
11543 session_deps_.socket_factory->AddSocketDataProvider(&data);
11544
11545 TestCompletionCallback callback;
11546
11547 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11548 EXPECT_EQ(ERR_IO_PENDING, rv);
11549
11550 rv = callback.WaitForResult();
11551 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11552
11553 EXPECT_EQ(NULL, trans->GetResponseInfo());
11554
11555 // We don't care whether this succeeds or fails, but it shouldn't crash.
11556 HttpRequestHeaders request_headers;
11557 trans->GetFullRequestHeaders(&request_headers);
11558}
11559
11560TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11561 HttpRequestInfo request;
11562 request.method = "GET";
11563 request.url = GURL("http://www.google.com/");
11564 request.load_flags = 0;
11565
[email protected]3fe8d2f82013-10-17 08:56:0711566 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411567 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711568 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411569
11570 MockWrite data_writes[] = {
11571 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11572 };
11573 MockRead data_reads[] = {
11574 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11575 };
11576
11577 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11578 data_writes, arraysize(data_writes));
11579 session_deps_.socket_factory->AddSocketDataProvider(&data);
11580
11581 TestCompletionCallback callback;
11582
11583 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11584 EXPECT_EQ(ERR_IO_PENDING, rv);
11585
11586 rv = callback.WaitForResult();
11587 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11588
11589 EXPECT_EQ(NULL, trans->GetResponseInfo());
11590
11591 HttpRequestHeaders request_headers;
11592 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11593 EXPECT_TRUE(request_headers.HasHeader("Host"));
11594}
11595
11596TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11597 HttpRequestInfo request;
11598 request.method = "GET";
11599 request.url = GURL("http://www.google.com/");
11600 request.load_flags = 0;
11601
[email protected]3fe8d2f82013-10-17 08:56:0711602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411603 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711604 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411605
11606 MockWrite data_writes[] = {
11607 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11608 };
11609 MockRead data_reads[] = {
11610 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11611 };
11612
11613 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11614 data_writes, arraysize(data_writes));
11615 session_deps_.socket_factory->AddSocketDataProvider(&data);
11616
11617 TestCompletionCallback callback;
11618
11619 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11620 EXPECT_EQ(ERR_IO_PENDING, rv);
11621
11622 rv = callback.WaitForResult();
11623 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11624
11625 EXPECT_EQ(NULL, trans->GetResponseInfo());
11626
11627 HttpRequestHeaders request_headers;
11628 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11629 EXPECT_TRUE(request_headers.HasHeader("Host"));
11630}
11631
11632TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11633 HttpRequestInfo request;
11634 request.method = "GET";
11635 request.url = GURL("http://www.google.com/");
11636 request.load_flags = 0;
11637
[email protected]3fe8d2f82013-10-17 08:56:0711638 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411639 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411641
11642 MockWrite data_writes[] = {
11643 MockWrite("GET / HTTP/1.1\r\n"
11644 "Host: www.google.com\r\n"
11645 "Connection: keep-alive\r\n\r\n"),
11646 };
11647 MockRead data_reads[] = {
11648 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11649 };
11650
11651 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11652 data_writes, arraysize(data_writes));
11653 session_deps_.socket_factory->AddSocketDataProvider(&data);
11654
11655 TestCompletionCallback callback;
11656
11657 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11658 EXPECT_EQ(ERR_IO_PENDING, rv);
11659
11660 rv = callback.WaitForResult();
11661 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11662
11663 EXPECT_EQ(NULL, trans->GetResponseInfo());
11664
11665 HttpRequestHeaders request_headers;
11666 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11667 EXPECT_TRUE(request_headers.HasHeader("Host"));
11668}
11669
11670TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11671 HttpRequestInfo request;
11672 request.method = "GET";
11673 request.url = GURL("http://www.google.com/");
11674 request.load_flags = 0;
11675
[email protected]3fe8d2f82013-10-17 08:56:0711676 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411677 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711678 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411679
11680 MockWrite data_writes[] = {
11681 MockWrite("GET / HTTP/1.1\r\n"
11682 "Host: www.google.com\r\n"
11683 "Connection: keep-alive\r\n\r\n"),
11684 };
11685 MockRead data_reads[] = {
11686 MockRead(ASYNC, ERR_CONNECTION_RESET),
11687 };
11688
11689 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11690 data_writes, arraysize(data_writes));
11691 session_deps_.socket_factory->AddSocketDataProvider(&data);
11692
11693 TestCompletionCallback callback;
11694
11695 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11696 EXPECT_EQ(ERR_IO_PENDING, rv);
11697
11698 rv = callback.WaitForResult();
11699 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11700
11701 EXPECT_EQ(NULL, trans->GetResponseInfo());
11702
11703 HttpRequestHeaders request_headers;
11704 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11705 EXPECT_TRUE(request_headers.HasHeader("Host"));
11706}
11707
11708TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11709 HttpRequestInfo request;
11710 request.method = "GET";
11711 request.url = GURL("http://www.google.com/");
11712 request.load_flags = 0;
11713 request.extra_headers.SetHeader("X-Foo", "bar");
11714
[email protected]3fe8d2f82013-10-17 08:56:0711715 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411716 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411718
11719 MockWrite data_writes[] = {
11720 MockWrite("GET / HTTP/1.1\r\n"
11721 "Host: www.google.com\r\n"
11722 "Connection: keep-alive\r\n"
11723 "X-Foo: bar\r\n\r\n"),
11724 };
11725 MockRead data_reads[] = {
11726 MockRead("HTTP/1.1 200 OK\r\n"
11727 "Content-Length: 5\r\n\r\n"
11728 "hello"),
11729 MockRead(ASYNC, ERR_UNEXPECTED),
11730 };
11731
11732 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11733 data_writes, arraysize(data_writes));
11734 session_deps_.socket_factory->AddSocketDataProvider(&data);
11735
11736 TestCompletionCallback callback;
11737
11738 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11739 EXPECT_EQ(ERR_IO_PENDING, rv);
11740
11741 rv = callback.WaitForResult();
11742 EXPECT_EQ(OK, rv);
11743
11744 HttpRequestHeaders request_headers;
11745 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11746 std::string foo;
11747 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11748 EXPECT_EQ("bar", foo);
11749}
11750
[email protected]bf828982013-08-14 18:01:4711751namespace {
11752
[email protected]e86839fd2013-08-14 18:29:0311753// Fake HttpStreamBase that simply records calls to SetPriority().
11754class FakeStream : public HttpStreamBase,
11755 public base::SupportsWeakPtr<FakeStream> {
11756 public:
11757 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
11758 virtual ~FakeStream() {}
11759
11760 RequestPriority priority() const { return priority_; }
11761
11762 virtual int InitializeStream(const HttpRequestInfo* request_info,
11763 RequestPriority priority,
11764 const BoundNetLog& net_log,
11765 const CompletionCallback& callback) OVERRIDE {
11766 return ERR_IO_PENDING;
11767 }
11768
11769 virtual int SendRequest(const HttpRequestHeaders& request_headers,
11770 HttpResponseInfo* response,
11771 const CompletionCallback& callback) OVERRIDE {
11772 ADD_FAILURE();
11773 return ERR_UNEXPECTED;
11774 }
11775
11776 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
11777 ADD_FAILURE();
11778 return ERR_UNEXPECTED;
11779 }
11780
11781 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
11782 ADD_FAILURE();
11783 return NULL;
11784 }
11785
11786 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
11787 const CompletionCallback& callback) OVERRIDE {
11788 ADD_FAILURE();
11789 return ERR_UNEXPECTED;
11790 }
11791
11792 virtual void Close(bool not_reusable) OVERRIDE {}
11793
11794 virtual bool IsResponseBodyComplete() const OVERRIDE {
11795 ADD_FAILURE();
11796 return false;
11797 }
11798
11799 virtual bool CanFindEndOfResponse() const OVERRIDE {
11800 return false;
11801 }
11802
11803 virtual bool IsConnectionReused() const OVERRIDE {
11804 ADD_FAILURE();
11805 return false;
11806 }
11807
11808 virtual void SetConnectionReused() OVERRIDE {
11809 ADD_FAILURE();
11810 }
11811
11812 virtual bool IsConnectionReusable() const OVERRIDE {
11813 ADD_FAILURE();
11814 return false;
11815 }
11816
11817 virtual bool GetLoadTimingInfo(
11818 LoadTimingInfo* load_timing_info) const OVERRIDE {
11819 ADD_FAILURE();
11820 return false;
11821 }
11822
11823 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
11824 ADD_FAILURE();
11825 }
11826
11827 virtual void GetSSLCertRequestInfo(
11828 SSLCertRequestInfo* cert_request_info) OVERRIDE {
11829 ADD_FAILURE();
11830 }
11831
11832 virtual bool IsSpdyHttpStream() const OVERRIDE {
11833 ADD_FAILURE();
11834 return false;
11835 }
11836
11837 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
11838 ADD_FAILURE();
11839 }
11840
11841 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11842 priority_ = priority;
11843 }
11844
11845 private:
11846 RequestPriority priority_;
11847
11848 DISALLOW_COPY_AND_ASSIGN(FakeStream);
11849};
11850
11851// Fake HttpStreamRequest that simply records calls to SetPriority()
11852// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4711853class FakeStreamRequest : public HttpStreamRequest,
11854 public base::SupportsWeakPtr<FakeStreamRequest> {
11855 public:
[email protected]e86839fd2013-08-14 18:29:0311856 FakeStreamRequest(RequestPriority priority,
11857 HttpStreamRequest::Delegate* delegate)
11858 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4411859 delegate_(delegate),
11860 websocket_stream_create_helper_(NULL) {}
11861
11862 FakeStreamRequest(RequestPriority priority,
11863 HttpStreamRequest::Delegate* delegate,
11864 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
11865 : priority_(priority),
11866 delegate_(delegate),
11867 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0311868
[email protected]bf828982013-08-14 18:01:4711869 virtual ~FakeStreamRequest() {}
11870
11871 RequestPriority priority() const { return priority_; }
11872
[email protected]831e4a32013-11-14 02:14:4411873 const WebSocketHandshakeStreamBase::CreateHelper*
11874 websocket_stream_create_helper() const {
11875 return websocket_stream_create_helper_;
11876 }
11877
[email protected]e86839fd2013-08-14 18:29:0311878 // Create a new FakeStream and pass it to the request's
11879 // delegate. Returns a weak pointer to the FakeStream.
11880 base::WeakPtr<FakeStream> FinishStreamRequest() {
11881 FakeStream* fake_stream = new FakeStream(priority_);
11882 // Do this before calling OnStreamReady() as OnStreamReady() may
11883 // immediately delete |fake_stream|.
11884 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
11885 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
11886 return weak_stream;
11887 }
11888
[email protected]bf828982013-08-14 18:01:4711889 virtual int RestartTunnelWithProxyAuth(
11890 const AuthCredentials& credentials) OVERRIDE {
11891 ADD_FAILURE();
11892 return ERR_UNEXPECTED;
11893 }
11894
11895 virtual LoadState GetLoadState() const OVERRIDE {
11896 ADD_FAILURE();
11897 return LoadState();
11898 }
11899
11900 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11901 priority_ = priority;
11902 }
11903
11904 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711905 return false;
11906 }
11907
11908 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711909 return kProtoUnknown;
11910 }
11911
11912 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711913 return false;
11914 }
11915
11916 private:
11917 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0311918 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4411919 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4711920
11921 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
11922};
11923
11924// Fake HttpStreamFactory that vends FakeStreamRequests.
11925class FakeStreamFactory : public HttpStreamFactory {
11926 public:
11927 FakeStreamFactory() {}
11928 virtual ~FakeStreamFactory() {}
11929
11930 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
11931 // RequestStream() (which may be NULL if it was destroyed already).
11932 base::WeakPtr<FakeStreamRequest> last_stream_request() {
11933 return last_stream_request_;
11934 }
11935
11936 virtual HttpStreamRequest* RequestStream(
11937 const HttpRequestInfo& info,
11938 RequestPriority priority,
11939 const SSLConfig& server_ssl_config,
11940 const SSLConfig& proxy_ssl_config,
11941 HttpStreamRequest::Delegate* delegate,
11942 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0311943 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4711944 last_stream_request_ = fake_request->AsWeakPtr();
11945 return fake_request;
11946 }
11947
[email protected]a9cf2b92013-10-30 12:08:4911948 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4711949 const HttpRequestInfo& info,
11950 RequestPriority priority,
11951 const SSLConfig& server_ssl_config,
11952 const SSLConfig& proxy_ssl_config,
11953 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4611954 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4711955 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4411956 FakeStreamRequest* fake_request =
11957 new FakeStreamRequest(priority, delegate, create_helper);
11958 last_stream_request_ = fake_request->AsWeakPtr();
11959 return fake_request;
[email protected]bf828982013-08-14 18:01:4711960 }
11961
11962 virtual void PreconnectStreams(int num_streams,
11963 const HttpRequestInfo& info,
11964 RequestPriority priority,
11965 const SSLConfig& server_ssl_config,
11966 const SSLConfig& proxy_ssl_config) OVERRIDE {
11967 ADD_FAILURE();
11968 }
11969
11970 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
11971 ADD_FAILURE();
11972 return NULL;
11973 }
11974
11975 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
11976 ADD_FAILURE();
11977 return NULL;
11978 }
11979
11980 private:
11981 base::WeakPtr<FakeStreamRequest> last_stream_request_;
11982
11983 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
11984};
11985
[email protected]831e4a32013-11-14 02:14:4411986// TODO(yhirano): Split this class out into a net/websockets file, if it is
11987// worth doing.
11988class FakeWebSocketStreamCreateHelper :
11989 public WebSocketHandshakeStreamBase::CreateHelper {
11990 public:
11991 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
11992 ClientSocketHandle* connection,
11993 bool using_proxy) OVERRIDE {
11994 NOTREACHED();
11995 return NULL;
11996 }
11997
11998 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
11999 const base::WeakPtr<SpdySession>& session,
12000 bool use_relative_url) OVERRIDE {
12001 NOTREACHED();
12002 return NULL;
12003 };
12004
12005 virtual ~FakeWebSocketStreamCreateHelper() {}
12006
12007 virtual scoped_ptr<WebSocketStream> Upgrade() {
12008 NOTREACHED();
12009 return scoped_ptr<WebSocketStream>();
12010 }
12011};
12012
[email protected]bf828982013-08-14 18:01:4712013} // namespace
12014
12015// Make sure that HttpNetworkTransaction passes on its priority to its
12016// stream request on start.
12017TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12018 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12019 HttpNetworkSessionPeer peer(session);
12020 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412021 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712022
12023 HttpNetworkTransaction trans(LOW, session);
12024
12025 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12026
12027 HttpRequestInfo request;
12028 TestCompletionCallback callback;
12029 EXPECT_EQ(ERR_IO_PENDING,
12030 trans.Start(&request, callback.callback(), BoundNetLog()));
12031
12032 base::WeakPtr<FakeStreamRequest> fake_request =
12033 fake_factory->last_stream_request();
12034 ASSERT_TRUE(fake_request != NULL);
12035 EXPECT_EQ(LOW, fake_request->priority());
12036}
12037
12038// Make sure that HttpNetworkTransaction passes on its priority
12039// updates to its stream request.
12040TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12041 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12042 HttpNetworkSessionPeer peer(session);
12043 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412044 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712045
12046 HttpNetworkTransaction trans(LOW, session);
12047
12048 HttpRequestInfo request;
12049 TestCompletionCallback callback;
12050 EXPECT_EQ(ERR_IO_PENDING,
12051 trans.Start(&request, callback.callback(), BoundNetLog()));
12052
12053 base::WeakPtr<FakeStreamRequest> fake_request =
12054 fake_factory->last_stream_request();
12055 ASSERT_TRUE(fake_request != NULL);
12056 EXPECT_EQ(LOW, fake_request->priority());
12057
12058 trans.SetPriority(LOWEST);
12059 ASSERT_TRUE(fake_request != NULL);
12060 EXPECT_EQ(LOWEST, fake_request->priority());
12061}
12062
[email protected]e86839fd2013-08-14 18:29:0312063// Make sure that HttpNetworkTransaction passes on its priority
12064// updates to its stream.
12065TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12066 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12067 HttpNetworkSessionPeer peer(session);
12068 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412069 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312070
12071 HttpNetworkTransaction trans(LOW, session);
12072
12073 HttpRequestInfo request;
12074 TestCompletionCallback callback;
12075 EXPECT_EQ(ERR_IO_PENDING,
12076 trans.Start(&request, callback.callback(), BoundNetLog()));
12077
12078 base::WeakPtr<FakeStreamRequest> fake_request =
12079 fake_factory->last_stream_request();
12080 ASSERT_TRUE(fake_request != NULL);
12081 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12082 ASSERT_TRUE(fake_stream != NULL);
12083 EXPECT_EQ(LOW, fake_stream->priority());
12084
12085 trans.SetPriority(LOWEST);
12086 EXPECT_EQ(LOWEST, fake_stream->priority());
12087}
12088
[email protected]831e4a32013-11-14 02:14:4412089TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12090 // The same logic needs to be tested for both ws: and wss: schemes, but this
12091 // test is already parameterised on NextProto, so it uses a loop to verify
12092 // that the different schemes work.
12093 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12094 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12095 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12096 HttpNetworkSessionPeer peer(session);
12097 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12098 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12099 peer.SetWebSocketHandshakeStreamFactory(
12100 scoped_ptr<HttpStreamFactory>(fake_factory));
12101
12102 HttpNetworkTransaction trans(LOW, session);
12103 trans.SetWebSocketHandshakeStreamCreateHelper(
12104 &websocket_stream_create_helper);
12105
12106 HttpRequestInfo request;
12107 TestCompletionCallback callback;
12108 request.method = "GET";
12109 request.url = GURL(test_cases[i]);
12110
12111 EXPECT_EQ(ERR_IO_PENDING,
12112 trans.Start(&request, callback.callback(), BoundNetLog()));
12113
12114 base::WeakPtr<FakeStreamRequest> fake_request =
12115 fake_factory->last_stream_request();
12116 ASSERT_TRUE(fake_request != NULL);
12117 EXPECT_EQ(&websocket_stream_create_helper,
12118 fake_request->websocket_stream_create_helper());
12119 }
12120}
12121
[email protected]043b68c82013-08-22 23:41:5212122// Tests that when a used socket is returned to the SSL socket pool, it's closed
12123// if the transport socket pool is stalled on the global socket limit.
12124TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12125 ClientSocketPoolManager::set_max_sockets_per_group(
12126 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12127 ClientSocketPoolManager::set_max_sockets_per_pool(
12128 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12129
12130 // Set up SSL request.
12131
12132 HttpRequestInfo ssl_request;
12133 ssl_request.method = "GET";
12134 ssl_request.url = GURL("https://www.google.com/");
12135
12136 MockWrite ssl_writes[] = {
12137 MockWrite("GET / HTTP/1.1\r\n"
12138 "Host: www.google.com\r\n"
12139 "Connection: keep-alive\r\n\r\n"),
12140 };
12141 MockRead ssl_reads[] = {
12142 MockRead("HTTP/1.1 200 OK\r\n"),
12143 MockRead("Content-Length: 11\r\n\r\n"),
12144 MockRead("hello world"),
12145 MockRead(SYNCHRONOUS, OK),
12146 };
12147 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12148 ssl_writes, arraysize(ssl_writes));
12149 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12150
12151 SSLSocketDataProvider ssl(ASYNC, OK);
12152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12153
12154 // Set up HTTP request.
12155
12156 HttpRequestInfo http_request;
12157 http_request.method = "GET";
12158 http_request.url = GURL("http://www.google.com/");
12159
12160 MockWrite http_writes[] = {
12161 MockWrite("GET / HTTP/1.1\r\n"
12162 "Host: www.google.com\r\n"
12163 "Connection: keep-alive\r\n\r\n"),
12164 };
12165 MockRead http_reads[] = {
12166 MockRead("HTTP/1.1 200 OK\r\n"),
12167 MockRead("Content-Length: 7\r\n\r\n"),
12168 MockRead("falafel"),
12169 MockRead(SYNCHRONOUS, OK),
12170 };
12171 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12172 http_writes, arraysize(http_writes));
12173 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12174
12175 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12176
12177 // Start the SSL request.
12178 TestCompletionCallback ssl_callback;
12179 scoped_ptr<HttpTransaction> ssl_trans(
12180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12181 ASSERT_EQ(ERR_IO_PENDING,
12182 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12183 BoundNetLog()));
12184
12185 // Start the HTTP request. Pool should stall.
12186 TestCompletionCallback http_callback;
12187 scoped_ptr<HttpTransaction> http_trans(
12188 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12189 ASSERT_EQ(ERR_IO_PENDING,
12190 http_trans->Start(&http_request, http_callback.callback(),
12191 BoundNetLog()));
12192 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12193
12194 // Wait for response from SSL request.
12195 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12196 std::string response_data;
12197 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12198 EXPECT_EQ("hello world", response_data);
12199
12200 // The SSL socket should automatically be closed, so the HTTP request can
12201 // start.
12202 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12203 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12204
12205 // The HTTP request can now complete.
12206 ASSERT_EQ(OK, http_callback.WaitForResult());
12207 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12208 EXPECT_EQ("falafel", response_data);
12209
12210 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12211}
12212
12213// Tests that when a SSL connection is established but there's no corresponding
12214// request that needs it, the new socket is closed if the transport socket pool
12215// is stalled on the global socket limit.
12216TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12217 ClientSocketPoolManager::set_max_sockets_per_group(
12218 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12219 ClientSocketPoolManager::set_max_sockets_per_pool(
12220 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12221
12222 // Set up an ssl request.
12223
12224 HttpRequestInfo ssl_request;
12225 ssl_request.method = "GET";
12226 ssl_request.url = GURL("https://www.foopy.com/");
12227
12228 // No data will be sent on the SSL socket.
12229 StaticSocketDataProvider ssl_data;
12230 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12231
12232 SSLSocketDataProvider ssl(ASYNC, OK);
12233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12234
12235 // Set up HTTP request.
12236
12237 HttpRequestInfo http_request;
12238 http_request.method = "GET";
12239 http_request.url = GURL("http://www.google.com/");
12240
12241 MockWrite http_writes[] = {
12242 MockWrite("GET / HTTP/1.1\r\n"
12243 "Host: www.google.com\r\n"
12244 "Connection: keep-alive\r\n\r\n"),
12245 };
12246 MockRead http_reads[] = {
12247 MockRead("HTTP/1.1 200 OK\r\n"),
12248 MockRead("Content-Length: 7\r\n\r\n"),
12249 MockRead("falafel"),
12250 MockRead(SYNCHRONOUS, OK),
12251 };
12252 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12253 http_writes, arraysize(http_writes));
12254 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12255
12256 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12257
12258 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12259 // cancelled when a normal transaction is cancelled.
12260 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12261 net::SSLConfig ssl_config;
12262 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12263 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12264 ssl_config, ssl_config);
12265 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12266
12267 // Start the HTTP request. Pool should stall.
12268 TestCompletionCallback http_callback;
12269 scoped_ptr<HttpTransaction> http_trans(
12270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12271 ASSERT_EQ(ERR_IO_PENDING,
12272 http_trans->Start(&http_request, http_callback.callback(),
12273 BoundNetLog()));
12274 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12275
12276 // The SSL connection will automatically be closed once the connection is
12277 // established, to let the HTTP request start.
12278 ASSERT_EQ(OK, http_callback.WaitForResult());
12279 std::string response_data;
12280 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12281 EXPECT_EQ("falafel", response_data);
12282
12283 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12284}
12285
[email protected]89ceba9a2009-03-21 03:46:0612286} // namespace net