blob: c60d6ecaea7e6b0360d2aeb48175a2aebe6b8455 [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"
initial.commit586acc5fe2008-07-26 22:42:5267#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1568#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2769#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5270
71//-----------------------------------------------------------------------------
72
[email protected]13c8a092010-07-29 06:15:4473namespace {
74
[email protected]42cba2fb2013-03-29 19:58:5775const base::string16 kBar(ASCIIToUTF16("bar"));
76const base::string16 kBar2(ASCIIToUTF16("bar2"));
77const base::string16 kBar3(ASCIIToUTF16("bar3"));
78const base::string16 kBaz(ASCIIToUTF16("baz"));
79const base::string16 kFirst(ASCIIToUTF16("first"));
80const base::string16 kFoo(ASCIIToUTF16("foo"));
81const base::string16 kFoo2(ASCIIToUTF16("foo2"));
82const base::string16 kFoo3(ASCIIToUTF16("foo3"));
83const base::string16 kFou(ASCIIToUTF16("fou"));
84const base::string16 kSecond(ASCIIToUTF16("second"));
85const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
86const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4487
[email protected]e5c026642012-03-17 00:14:0288int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
89 return session->GetTransportSocketPool(
90 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
91}
92
93int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
94 return session->GetSSLSocketPool(
95 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
96}
97
[email protected]043b68c82013-08-22 23:41:5298bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
99 return session->GetTransportSocketPool(
100 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
101}
102
[email protected]f3da152d2012-06-02 01:00:57103// Takes in a Value created from a NetLogHttpResponseParameter, and returns
104// a JSONified list of headers as a single string. Uses single quotes instead
105// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27106bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57107 if (!params)
108 return false;
[email protected]ea5ef4c2013-06-13 22:50:27109 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57110 if (!params->GetList("headers", &header_list))
111 return false;
112 std::string double_quote_headers;
113 base::JSONWriter::Write(header_list, &double_quote_headers);
114 ReplaceChars(double_quote_headers, "\"", "'", headers);
115 return true;
116}
117
[email protected]029c83b62013-01-24 05:28:20118// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
119// used.
120void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
121 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25122 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
123
[email protected]029c83b62013-01-24 05:28:20124 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
125 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
126
127 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
128 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25129
130 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25131
[email protected]3b23a222013-05-15 21:33:25132 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25133 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
134 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25135 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25136}
137
[email protected]029c83b62013-01-24 05:28:20138// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
139// used.
[email protected]58e32bb2013-01-21 18:23:25140void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
141 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20142 EXPECT_FALSE(load_timing_info.socket_reused);
143 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
144
145 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
146 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
147
148 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25149 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20150 EXPECT_LE(load_timing_info.connect_timing.connect_end,
151 load_timing_info.send_start);
152
153 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20154
[email protected]3b23a222013-05-15 21:33:25155 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20156 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
157 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25158 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20159}
160
161// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
162// used.
163void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
164 EXPECT_TRUE(load_timing_info.socket_reused);
165 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
166
167 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
168
169 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
170 EXPECT_LE(load_timing_info.proxy_resolve_start,
171 load_timing_info.proxy_resolve_end);
172 EXPECT_LE(load_timing_info.proxy_resolve_end,
173 load_timing_info.send_start);
174 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20175
[email protected]3b23a222013-05-15 21:33:25176 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20177 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
178 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25179 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20180}
181
182// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
183// used.
184void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
185 int connect_timing_flags) {
186 EXPECT_FALSE(load_timing_info.socket_reused);
187 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
188
189 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
190 EXPECT_LE(load_timing_info.proxy_resolve_start,
191 load_timing_info.proxy_resolve_end);
192 EXPECT_LE(load_timing_info.proxy_resolve_end,
193 load_timing_info.connect_timing.connect_start);
194 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
195 connect_timing_flags);
196 EXPECT_LE(load_timing_info.connect_timing.connect_end,
197 load_timing_info.send_start);
198
199 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20200
[email protected]3b23a222013-05-15 21:33:25201 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20202 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
203 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25204 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25205}
206
[email protected]13c8a092010-07-29 06:15:44207} // namespace
208
[email protected]89ceba9a2009-03-21 03:46:06209namespace net {
210
[email protected]448d4ca52012-03-04 04:12:23211namespace {
212
[email protected]c6bf8152012-12-02 07:43:34213HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
214 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14215}
216
[email protected]448d4ca52012-03-04 04:12:23217} // namespace
218
[email protected]23e482282013-06-14 16:08:02219class HttpNetworkTransactionTest
220 : public PlatformTest,
221 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03222 public:
[email protected]23e482282013-06-14 16:08:02223 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03224 // Important to restore the per-pool limit first, since the pool limit must
225 // always be greater than group limit, and the tests reduce both limits.
226 ClientSocketPoolManager::set_max_sockets_per_pool(
227 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
228 ClientSocketPoolManager::set_max_sockets_per_group(
229 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
230 }
231
[email protected]e3ceb682011-06-28 23:55:46232 protected:
[email protected]23e482282013-06-14 16:08:02233 HttpNetworkTransactionTest()
234 : spdy_util_(GetParam()),
235 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03236 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
237 HttpNetworkSession::NORMAL_SOCKET_POOL)),
238 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
239 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
240 }
[email protected]bb88e1d32013-05-03 23:11:07241
[email protected]e3ceb682011-06-28 23:55:46242 struct SimpleGetHelperResult {
243 int rv;
244 std::string status_line;
245 std::string response_data;
[email protected]58e32bb2013-01-21 18:23:25246 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46247 };
248
[email protected]2ff8b312010-04-26 22:20:54249 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50250 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34251 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54252 }
253
[email protected]0e75a732008-10-16 20:36:09254 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50255 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34256 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09257 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34258 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09259 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50260 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34261 base::MessageLoop::current()->RunUntilIdle();
[email protected]c54c6962013-02-01 04:53:19262 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:16263 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]0e75a732008-10-16 20:36:09264 }
265
[email protected]8a0fc822013-06-27 20:52:43266 // This is the expected return from a current server advertising SPDY.
267 std::string GetAlternateProtocolHttpHeader() {
268 return
269 std::string("Alternate-Protocol: 443:") +
270 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
271 "\r\n\r\n";
272 }
273
[email protected]202965992011-12-07 23:04:51274 // Either |write_failure| specifies a write failure or |read_failure|
275 // specifies a read failure when using a reused socket. In either case, the
276 // failure should cause the network transaction to resend the request, and the
277 // other argument should be NULL.
278 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
279 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52280
[email protected]5a60c8b2011-10-19 20:14:29281 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
282 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15283 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52284
[email protected]ff007e162009-05-23 09:13:15285 HttpRequestInfo request;
286 request.method = "GET";
287 request.url = GURL("http://www.google.com/");
288 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52289
[email protected]58e32bb2013-01-21 18:23:25290 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07291 session_deps_.net_log = log.bound().net_log();
[email protected]cb9bf6ca2011-01-28 13:15:27292 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36293 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07294 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:27295
[email protected]5a60c8b2011-10-19 20:14:29296 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07297 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29298 }
initial.commit586acc5fe2008-07-26 22:42:52299
[email protected]49639fa2011-12-20 23:22:41300 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52301
[email protected]3deb9a52010-11-11 00:24:40302 EXPECT_TRUE(log.bound().IsLoggingAllEvents());
[email protected]49639fa2011-12-20 23:22:41303 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15304 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52305
[email protected]ff007e162009-05-23 09:13:15306 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25307
308 // Even in the failure cases that use this function, connections are always
309 // successfully established before the error.
310 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
311 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
312
[email protected]ff007e162009-05-23 09:13:15313 if (out.rv != OK)
314 return out;
315
316 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50317 // Can't use ASSERT_* inside helper functions like this, so
318 // return an error.
[email protected]90499482013-06-01 00:39:50319 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50320 out.rv = ERR_UNEXPECTED;
321 return out;
322 }
[email protected]ff007e162009-05-23 09:13:15323 out.status_line = response->headers->GetStatusLine();
324
[email protected]80a09a82012-11-16 17:40:06325 EXPECT_EQ("127.0.0.1", response->socket_address.host());
326 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19327
[email protected]ff007e162009-05-23 09:13:15328 rv = ReadTransaction(trans.get(), &out.response_data);
329 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40330
[email protected]f3da152d2012-06-02 01:00:57331 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40332 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39333 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40334 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12335 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39336 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40337 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39338 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
339 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15340
[email protected]f3da152d2012-06-02 01:00:57341 std::string line;
342 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
343 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
344
[email protected]79e1fd62013-06-20 06:50:04345 HttpRequestHeaders request_headers;
346 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
347 std::string value;
348 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
349 EXPECT_EQ("www.google.com", value);
350 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
351 EXPECT_EQ("keep-alive", value);
352
353 std::string response_headers;
354 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
355 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
356 response_headers);
[email protected]3deb9a52010-11-11 00:24:40357
[email protected]aecfbf22008-10-16 02:02:47358 return out;
[email protected]ff007e162009-05-23 09:13:15359 }
initial.commit586acc5fe2008-07-26 22:42:52360
[email protected]5a60c8b2011-10-19 20:14:29361 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
362 size_t reads_count) {
363 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
364 StaticSocketDataProvider* data[] = { &reads };
365 return SimpleGetHelperForData(data, 1);
366 }
367
[email protected]ff007e162009-05-23 09:13:15368 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
369 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52370
[email protected]ff007e162009-05-23 09:13:15371 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07372
373 void BypassHostCacheOnRefreshHelper(int load_flags);
374
375 void CheckErrorIsPassedBack(int error, IoMode mode);
376
[email protected]4bd46222013-05-14 19:32:23377 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07378 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03379
380 // Original socket limits. Some tests set these. Safest to always restore
381 // them once each test has been run.
382 int old_max_group_sockets_;
383 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15384};
[email protected]231d5a32008-09-13 00:45:27385
[email protected]23e482282013-06-14 16:08:02386INSTANTIATE_TEST_CASE_P(
387 NextProto,
388 HttpNetworkTransactionTest,
[email protected]88a332622013-07-30 07:13:32389 testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
390 kProtoHTTP2Draft04));
[email protected]23e482282013-06-14 16:08:02391
[email protected]448d4ca52012-03-04 04:12:23392namespace {
393
[email protected]15a5ccf82008-10-23 19:57:43394// Fill |str| with a long header list that consumes >= |size| bytes.
395void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19396 const char* row =
397 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
398 const int sizeof_row = strlen(row);
399 const int num_rows = static_cast<int>(
400 ceil(static_cast<float>(size) / sizeof_row));
401 const int sizeof_data = num_rows * sizeof_row;
402 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43403 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51404
[email protected]4ddaf2502008-10-23 18:26:19405 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43406 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19407}
408
[email protected]385a4672009-03-11 22:21:29409// Alternative functions that eliminate randomness and dependency on the local
410// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20411void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29412 static const uint8 bytes[] = {
413 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
414 };
415 static size_t current_byte = 0;
416 for (size_t i = 0; i < n; ++i) {
417 output[i] = bytes[current_byte++];
418 current_byte %= arraysize(bytes);
419 }
420}
421
[email protected]fe2bc6a2009-03-23 16:52:20422void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29423 static const uint8 bytes[] = {
424 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
425 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
426 };
427 static size_t current_byte = 0;
428 for (size_t i = 0; i < n; ++i) {
429 output[i] = bytes[current_byte++];
430 current_byte %= arraysize(bytes);
431 }
432}
433
[email protected]fe2bc6a2009-03-23 16:52:20434std::string MockGetHostName() {
435 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29436}
437
[email protected]e60e47a2010-07-14 03:37:18438template<typename ParentPool>
439class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31440 public:
[email protected]9e1bdd32011-02-03 21:48:34441 CaptureGroupNameSocketPool(HostResolver* host_resolver,
442 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18443
[email protected]d80a4322009-08-14 07:07:49444 const std::string last_group_name_received() const {
445 return last_group_name_;
446 }
447
[email protected]684970b2009-08-14 04:54:46448 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49449 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31450 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31451 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41452 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53453 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31454 last_group_name_ = group_name;
455 return ERR_IO_PENDING;
456 }
[email protected]04e5be32009-06-26 20:00:31457 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21458 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31459 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44460 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19461 int id) {}
[email protected]04e5be32009-06-26 20:00:31462 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31463 virtual int IdleSocketCount() const {
464 return 0;
465 }
466 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
467 return 0;
468 }
469 virtual LoadState GetLoadState(const std::string& group_name,
470 const ClientSocketHandle* handle) const {
471 return LOAD_STATE_IDLE;
472 }
[email protected]a796bcec2010-03-22 17:17:26473 virtual base::TimeDelta ConnectionTimeout() const {
474 return base::TimeDelta();
475 }
[email protected]d80a4322009-08-14 07:07:49476
477 private:
[email protected]04e5be32009-06-26 20:00:31478 std::string last_group_name_;
479};
480
[email protected]ab739042011-04-07 15:22:28481typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
482CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13483typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
484CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06485typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11486CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18487typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
488CaptureGroupNameSSLSocketPool;
489
490template<typename ParentPool>
491CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34492 HostResolver* host_resolver,
493 CertVerifier* /* cert_verifier */)
494 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18495
496template<>
[email protected]2df19bb2010-08-25 20:13:46497CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34498 HostResolver* host_resolver,
499 CertVerifier* /* cert_verifier */)
500 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46501
[email protected]007b3f82013-04-09 08:46:45502template <>
[email protected]e60e47a2010-07-14 03:37:18503CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34504 HostResolver* host_resolver,
505 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45506 : SSLClientSocketPool(0,
507 0,
508 NULL,
509 host_resolver,
510 cert_verifier,
511 NULL,
512 NULL,
513 std::string(),
514 NULL,
515 NULL,
516 NULL,
517 NULL,
518 NULL,
519 NULL) {}
[email protected]2227c692010-05-04 15:36:11520
[email protected]231d5a32008-09-13 00:45:27521//-----------------------------------------------------------------------------
522
[email protected]79cb5c12011-09-12 13:12:04523// Helper functions for validating that AuthChallengeInfo's are correctly
524// configured for common cases.
525bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
526 if (!auth_challenge)
527 return false;
528 EXPECT_FALSE(auth_challenge->is_proxy);
529 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
530 EXPECT_EQ("MyRealm1", auth_challenge->realm);
531 EXPECT_EQ("basic", auth_challenge->scheme);
532 return true;
533}
534
535bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
536 if (!auth_challenge)
537 return false;
538 EXPECT_TRUE(auth_challenge->is_proxy);
539 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
540 EXPECT_EQ("MyRealm1", auth_challenge->realm);
541 EXPECT_EQ("basic", auth_challenge->scheme);
542 return true;
543}
544
545bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
546 if (!auth_challenge)
547 return false;
548 EXPECT_FALSE(auth_challenge->is_proxy);
549 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
550 EXPECT_EQ("digestive", auth_challenge->realm);
551 EXPECT_EQ("digest", auth_challenge->scheme);
552 return true;
553}
554
555bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
556 if (!auth_challenge)
557 return false;
558 EXPECT_FALSE(auth_challenge->is_proxy);
559 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
560 EXPECT_EQ(std::string(), auth_challenge->realm);
561 EXPECT_EQ("ntlm", auth_challenge->scheme);
562 return true;
563}
564
[email protected]448d4ca52012-03-04 04:12:23565} // namespace
566
[email protected]23e482282013-06-14 16:08:02567TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]d207a5f2009-06-04 05:28:40568 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36569 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07570 CreateSession(&session_deps_)));
[email protected]231d5a32008-09-13 00:45:27571}
572
[email protected]23e482282013-06-14 16:08:02573TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27574 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35575 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
576 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06577 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27578 };
[email protected]31a2bfe2010-02-09 08:03:39579 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
580 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42581 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27582 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
583 EXPECT_EQ("hello world", out.response_data);
584}
585
586// Response with no status line.
[email protected]23e482282013-06-14 16:08:02587TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27588 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35589 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06590 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27591 };
[email protected]31a2bfe2010-02-09 08:03:39592 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
593 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42594 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27595 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
596 EXPECT_EQ("hello world", out.response_data);
597}
598
599// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02600TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27601 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35602 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06603 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27604 };
[email protected]31a2bfe2010-02-09 08:03:39605 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
606 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42607 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27608 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
609 EXPECT_EQ("DATA", out.response_data);
610}
611
612// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02613TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27614 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35615 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06616 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27617 };
[email protected]31a2bfe2010-02-09 08:03:39618 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
619 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42620 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27621 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
622 EXPECT_EQ("DATA", out.response_data);
623}
624
625// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02626TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27627 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35628 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06629 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27630 };
[email protected]31a2bfe2010-02-09 08:03:39631 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
632 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42633 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25634 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
635 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27636}
637
638// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02639TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27640 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35641 MockRead("\n"),
642 MockRead("\n"),
643 MockRead("Q"),
644 MockRead("J"),
645 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06646 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27647 };
[email protected]31a2bfe2010-02-09 08:03:39648 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
649 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42650 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27651 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
652 EXPECT_EQ("DATA", out.response_data);
653}
654
655// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02656TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27657 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35658 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06659 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27660 };
[email protected]31a2bfe2010-02-09 08:03:39661 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
662 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42663 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27664 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
665 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52666}
667
[email protected]f9d44aa2008-09-23 23:57:17668// Simulate a 204 response, lacking a Content-Length header, sent over a
669// persistent connection. The response should still terminate since a 204
670// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02671TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]f9d44aa2008-09-23 23:57:17672 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35673 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
674 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06675 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17676 };
[email protected]31a2bfe2010-02-09 08:03:39677 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
678 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42679 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17680 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
681 EXPECT_EQ("", out.response_data);
682}
683
[email protected]0877e3d2009-10-17 22:29:57684// A simple request using chunked encoding with some extra data after.
685// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02686TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]0877e3d2009-10-17 22:29:57687 MockRead data_reads[] = {
688 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
689 MockRead("5\r\nHello\r\n"),
690 MockRead("1\r\n"),
691 MockRead(" \r\n"),
692 MockRead("5\r\nworld\r\n"),
693 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06694 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57695 };
[email protected]31a2bfe2010-02-09 08:03:39696 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
697 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57698 EXPECT_EQ(OK, out.rv);
699 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
700 EXPECT_EQ("Hello world", out.response_data);
701}
702
[email protected]9fe44f52010-09-23 18:36:00703// Next tests deal with http://crbug.com/56344.
704
[email protected]23e482282013-06-14 16:08:02705TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00706 MultipleContentLengthHeadersNoTransferEncoding) {
707 MockRead data_reads[] = {
708 MockRead("HTTP/1.1 200 OK\r\n"),
709 MockRead("Content-Length: 10\r\n"),
710 MockRead("Content-Length: 5\r\n\r\n"),
711 };
712 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
713 arraysize(data_reads));
714 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
715}
716
[email protected]23e482282013-06-14 16:08:02717TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04718 DuplicateContentLengthHeadersNoTransferEncoding) {
719 MockRead data_reads[] = {
720 MockRead("HTTP/1.1 200 OK\r\n"),
721 MockRead("Content-Length: 5\r\n"),
722 MockRead("Content-Length: 5\r\n\r\n"),
723 MockRead("Hello"),
724 };
725 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
726 arraysize(data_reads));
727 EXPECT_EQ(OK, out.rv);
728 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
729 EXPECT_EQ("Hello", out.response_data);
730}
731
[email protected]23e482282013-06-14 16:08:02732TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04733 ComplexContentLengthHeadersNoTransferEncoding) {
734 // More than 2 dupes.
735 {
736 MockRead data_reads[] = {
737 MockRead("HTTP/1.1 200 OK\r\n"),
738 MockRead("Content-Length: 5\r\n"),
739 MockRead("Content-Length: 5\r\n"),
740 MockRead("Content-Length: 5\r\n\r\n"),
741 MockRead("Hello"),
742 };
743 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
744 arraysize(data_reads));
745 EXPECT_EQ(OK, out.rv);
746 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
747 EXPECT_EQ("Hello", out.response_data);
748 }
749 // HTTP/1.0
750 {
751 MockRead data_reads[] = {
752 MockRead("HTTP/1.0 200 OK\r\n"),
753 MockRead("Content-Length: 5\r\n"),
754 MockRead("Content-Length: 5\r\n"),
755 MockRead("Content-Length: 5\r\n\r\n"),
756 MockRead("Hello"),
757 };
758 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
759 arraysize(data_reads));
760 EXPECT_EQ(OK, out.rv);
761 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
762 EXPECT_EQ("Hello", out.response_data);
763 }
764 // 2 dupes and one mismatched.
765 {
766 MockRead data_reads[] = {
767 MockRead("HTTP/1.1 200 OK\r\n"),
768 MockRead("Content-Length: 10\r\n"),
769 MockRead("Content-Length: 10\r\n"),
770 MockRead("Content-Length: 5\r\n\r\n"),
771 };
772 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
773 arraysize(data_reads));
774 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
775 }
776}
777
[email protected]23e482282013-06-14 16:08:02778TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00779 MultipleContentLengthHeadersTransferEncoding) {
780 MockRead data_reads[] = {
781 MockRead("HTTP/1.1 200 OK\r\n"),
782 MockRead("Content-Length: 666\r\n"),
783 MockRead("Content-Length: 1337\r\n"),
784 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
785 MockRead("5\r\nHello\r\n"),
786 MockRead("1\r\n"),
787 MockRead(" \r\n"),
788 MockRead("5\r\nworld\r\n"),
789 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06790 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00791 };
792 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
793 arraysize(data_reads));
794 EXPECT_EQ(OK, out.rv);
795 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
796 EXPECT_EQ("Hello world", out.response_data);
797}
798
[email protected]1628fe92011-10-04 23:04:55799// Next tests deal with http://crbug.com/98895.
800
801// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02802TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55803 MockRead data_reads[] = {
804 MockRead("HTTP/1.1 200 OK\r\n"),
805 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
806 MockRead("Content-Length: 5\r\n\r\n"),
807 MockRead("Hello"),
808 };
809 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
810 arraysize(data_reads));
811 EXPECT_EQ(OK, out.rv);
812 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
813 EXPECT_EQ("Hello", out.response_data);
814}
815
[email protected]54a9c6e52012-03-21 20:10:59816// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02817TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59818 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55819 MockRead data_reads[] = {
820 MockRead("HTTP/1.1 200 OK\r\n"),
821 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
822 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
823 MockRead("Content-Length: 5\r\n\r\n"),
824 MockRead("Hello"),
825 };
826 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
827 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59828 EXPECT_EQ(OK, out.rv);
829 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
830 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55831}
832
833// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02834TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55835 MockRead data_reads[] = {
836 MockRead("HTTP/1.1 200 OK\r\n"),
837 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
838 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
839 MockRead("Content-Length: 5\r\n\r\n"),
840 MockRead("Hello"),
841 };
842 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
843 arraysize(data_reads));
844 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
845}
846
[email protected]54a9c6e52012-03-21 20:10:59847// Checks that two identical Location headers result in no error.
848// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02849TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55850 MockRead data_reads[] = {
851 MockRead("HTTP/1.1 302 Redirect\r\n"),
852 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59853 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55854 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06855 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55856 };
857
858 HttpRequestInfo request;
859 request.method = "GET";
860 request.url = GURL("http://redirect.com/");
861 request.load_flags = 0;
862
[email protected]1628fe92011-10-04 23:04:55863 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36864 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07865 CreateSession(&session_deps_)));
[email protected]1628fe92011-10-04 23:04:55866
867 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07868 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55869
[email protected]49639fa2011-12-20 23:22:41870 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55871
[email protected]49639fa2011-12-20 23:22:41872 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55873 EXPECT_EQ(ERR_IO_PENDING, rv);
874
875 EXPECT_EQ(OK, callback.WaitForResult());
876
877 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50878 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55879 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
880 std::string url;
881 EXPECT_TRUE(response->headers->IsRedirect(&url));
882 EXPECT_EQ("http://good.com/", url);
883}
884
[email protected]1628fe92011-10-04 23:04:55885// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02886TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55887 MockRead data_reads[] = {
888 MockRead("HTTP/1.1 302 Redirect\r\n"),
889 MockRead("Location: http://good.com/\r\n"),
890 MockRead("Location: http://evil.com/\r\n"),
891 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06892 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55893 };
894 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
895 arraysize(data_reads));
896 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
897}
898
[email protected]ef0faf2e72009-03-05 23:27:23899// Do a request using the HEAD method. Verify that we don't try to read the
900// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02901TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42902 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23903 request.method = "HEAD";
904 request.url = GURL("http://www.google.com/");
905 request.load_flags = 0;
906
[email protected]cb9bf6ca2011-01-28 13:15:27907 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36908 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07909 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:27910
[email protected]ef0faf2e72009-03-05 23:27:23911 MockWrite data_writes1[] = {
912 MockWrite("HEAD / HTTP/1.1\r\n"
913 "Host: www.google.com\r\n"
914 "Connection: keep-alive\r\n"
915 "Content-Length: 0\r\n\r\n"),
916 };
917 MockRead data_reads1[] = {
918 MockRead("HTTP/1.1 404 Not Found\r\n"),
919 MockRead("Server: Blah\r\n"),
920 MockRead("Content-Length: 1234\r\n\r\n"),
921
922 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06923 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23924 };
925
[email protected]31a2bfe2010-02-09 08:03:39926 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
927 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07928 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23929
[email protected]49639fa2011-12-20 23:22:41930 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23931
[email protected]49639fa2011-12-20 23:22:41932 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42933 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23934
935 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42936 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23937
[email protected]1c773ea12009-04-28 19:58:42938 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50939 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23940
941 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:50942 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23943 EXPECT_EQ(1234, response->headers->GetContentLength());
944 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
945
946 std::string server_header;
947 void* iter = NULL;
948 bool has_server_header = response->headers->EnumerateHeader(
949 &iter, "Server", &server_header);
950 EXPECT_TRUE(has_server_header);
951 EXPECT_EQ("Blah", server_header);
952
953 // Reading should give EOF right away, since there is no message body
954 // (despite non-zero content-length).
955 std::string response_data;
956 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42957 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23958 EXPECT_EQ("", response_data);
959}
960
[email protected]23e482282013-06-14 16:08:02961TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:07962 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:52963
964 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35965 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
966 MockRead("hello"),
967 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
968 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:06969 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:52970 };
[email protected]31a2bfe2010-02-09 08:03:39971 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07972 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52973
[email protected]0b0bf032010-09-21 18:08:50974 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:52975 "hello", "world"
976 };
977
978 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42979 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52980 request.method = "GET";
981 request.url = GURL("http://www.google.com/");
982 request.load_flags = 0;
983
[email protected]262eec82013-03-19 21:01:36984 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:50985 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27986
[email protected]49639fa2011-12-20 23:22:41987 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52988
[email protected]49639fa2011-12-20 23:22:41989 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42990 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52991
992 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42993 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52994
[email protected]1c773ea12009-04-28 19:58:42995 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50996 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:52997
[email protected]90499482013-06-01 00:39:50998 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:25999 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521000
1001 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571002 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421003 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251004 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521005 }
1006}
1007
[email protected]23e482282013-06-14 16:08:021008TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061009 ScopedVector<UploadElementReader> element_readers;
1010 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201011 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271012
[email protected]1c773ea12009-04-28 19:58:421013 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521014 request.method = "POST";
1015 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271016 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521017 request.load_flags = 0;
1018
[email protected]cb9bf6ca2011-01-28 13:15:271019 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361020 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071021 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271022
initial.commit586acc5fe2008-07-26 22:42:521023 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351024 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1025 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1026 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061027 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521028 };
[email protected]31a2bfe2010-02-09 08:03:391029 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071030 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521031
[email protected]49639fa2011-12-20 23:22:411032 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521033
[email protected]49639fa2011-12-20 23:22:411034 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421035 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521036
1037 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421038 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521039
[email protected]1c773ea12009-04-28 19:58:421040 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501041 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521042
[email protected]90499482013-06-01 00:39:501043 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251044 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521045
1046 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571047 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421048 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251049 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521050}
1051
[email protected]3a2d3662009-03-27 03:49:141052// This test is almost the same as Ignores100 above, but the response contains
1053// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571054// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021055TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421056 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141057 request.method = "GET";
1058 request.url = GURL("http://www.foo.com/");
1059 request.load_flags = 0;
1060
[email protected]cb9bf6ca2011-01-28 13:15:271061 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361062 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071063 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271064
[email protected]3a2d3662009-03-27 03:49:141065 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571066 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1067 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141068 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061069 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141070 };
[email protected]31a2bfe2010-02-09 08:03:391071 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071072 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141073
[email protected]49639fa2011-12-20 23:22:411074 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141075
[email protected]49639fa2011-12-20 23:22:411076 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421077 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141078
1079 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421080 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141081
[email protected]1c773ea12009-04-28 19:58:421082 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501083 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141084
[email protected]90499482013-06-01 00:39:501085 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1087
1088 std::string response_data;
1089 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421090 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141091 EXPECT_EQ("hello world", response_data);
1092}
1093
[email protected]23e482282013-06-14 16:08:021094TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381095 HttpRequestInfo request;
1096 request.method = "POST";
1097 request.url = GURL("http://www.foo.com/");
1098 request.load_flags = 0;
1099
[email protected]cb9bf6ca2011-01-28 13:15:271100 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361101 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071102 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271103
[email protected]ee9410e72010-01-07 01:42:381104 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061105 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1106 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381107 };
[email protected]31a2bfe2010-02-09 08:03:391108 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381110
[email protected]49639fa2011-12-20 23:22:411111 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381112
[email protected]49639fa2011-12-20 23:22:411113 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381114 EXPECT_EQ(ERR_IO_PENDING, rv);
1115
1116 rv = callback.WaitForResult();
1117 EXPECT_EQ(OK, rv);
1118
1119 std::string response_data;
1120 rv = ReadTransaction(trans.get(), &response_data);
1121 EXPECT_EQ(OK, rv);
1122 EXPECT_EQ("", response_data);
1123}
1124
[email protected]23e482282013-06-14 16:08:021125TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381126 HttpRequestInfo request;
1127 request.method = "POST";
1128 request.url = GURL("http://www.foo.com/");
1129 request.load_flags = 0;
1130
[email protected]cb9bf6ca2011-01-28 13:15:271131 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361132 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071133 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271134
[email protected]ee9410e72010-01-07 01:42:381135 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061136 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381137 };
[email protected]31a2bfe2010-02-09 08:03:391138 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071139 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381140
[email protected]49639fa2011-12-20 23:22:411141 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381142
[email protected]49639fa2011-12-20 23:22:411143 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381144 EXPECT_EQ(ERR_IO_PENDING, rv);
1145
1146 rv = callback.WaitForResult();
1147 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1148}
1149
[email protected]23e482282013-06-14 16:08:021150void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511151 const MockWrite* write_failure,
1152 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421153 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521154 request.method = "GET";
1155 request.url = GURL("http://www.foo.com/");
1156 request.load_flags = 0;
1157
[email protected]58e32bb2013-01-21 18:23:251158 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071159 session_deps_.net_log = &net_log;
1160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271161
[email protected]202965992011-12-07 23:04:511162 // Written data for successfully sending both requests.
1163 MockWrite data1_writes[] = {
1164 MockWrite("GET / HTTP/1.1\r\n"
1165 "Host: www.foo.com\r\n"
1166 "Connection: keep-alive\r\n\r\n"),
1167 MockWrite("GET / HTTP/1.1\r\n"
1168 "Host: www.foo.com\r\n"
1169 "Connection: keep-alive\r\n\r\n")
1170 };
1171
1172 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521173 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351174 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1175 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061176 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521177 };
[email protected]202965992011-12-07 23:04:511178
1179 if (write_failure) {
1180 ASSERT_TRUE(!read_failure);
1181 data1_writes[1] = *write_failure;
1182 } else {
1183 ASSERT_TRUE(read_failure);
1184 data1_reads[2] = *read_failure;
1185 }
1186
1187 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1188 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071189 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521190
1191 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351192 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1193 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061194 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521195 };
[email protected]31a2bfe2010-02-09 08:03:391196 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071197 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521198
1199 const char* kExpectedResponseData[] = {
1200 "hello", "world"
1201 };
1202
[email protected]58e32bb2013-01-21 18:23:251203 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521204 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411205 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521206
[email protected]262eec82013-03-19 21:01:361207 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521209
[email protected]49639fa2011-12-20 23:22:411210 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421211 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521212
1213 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421214 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521215
[email protected]58e32bb2013-01-21 18:23:251216 LoadTimingInfo load_timing_info;
1217 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1218 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1219 if (i == 0) {
1220 first_socket_log_id = load_timing_info.socket_log_id;
1221 } else {
1222 // The second request should be using a new socket.
1223 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1224 }
1225
[email protected]1c773ea12009-04-28 19:58:421226 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501227 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521228
[email protected]90499482013-06-01 00:39:501229 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251230 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521231
1232 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571233 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421234 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251235 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521236 }
1237}
[email protected]3d2a59b2008-09-26 19:44:251238
[email protected]23e482282013-06-14 16:08:021239TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231240 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061241 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511242 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1243}
1244
[email protected]23e482282013-06-14 16:08:021245TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061246 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511247 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251248}
1249
[email protected]23e482282013-06-14 16:08:021250TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061251 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511252 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251253}
1254
[email protected]23e482282013-06-14 16:08:021255TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421256 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251257 request.method = "GET";
1258 request.url = GURL("http://www.google.com/");
1259 request.load_flags = 0;
1260
[email protected]cb9bf6ca2011-01-28 13:15:271261 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361262 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071263 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271264
[email protected]3d2a59b2008-09-26 19:44:251265 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061266 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351267 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1268 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061269 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251270 };
[email protected]31a2bfe2010-02-09 08:03:391271 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071272 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251273
[email protected]49639fa2011-12-20 23:22:411274 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251275
[email protected]49639fa2011-12-20 23:22:411276 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421277 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251278
1279 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421280 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251281
[email protected]1c773ea12009-04-28 19:58:421282 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251283 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251284}
1285
1286// What do various browsers do when the server closes a non-keepalive
1287// connection without sending any response header or body?
1288//
1289// IE7: error page
1290// Safari 3.1.2 (Windows): error page
1291// Firefox 3.0.1: blank page
1292// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421293// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1294// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021295TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251296 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061297 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351298 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1299 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061300 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251301 };
[email protected]31a2bfe2010-02-09 08:03:391302 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1303 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421304 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251305}
[email protected]038e9a32008-10-08 22:40:161306
[email protected]7a5378b2012-11-04 03:25:171307// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1308// tests. There was a bug causing HttpNetworkTransaction to hang in the
1309// destructor in such situations.
1310// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021311TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171312 HttpRequestInfo request;
1313 request.method = "GET";
1314 request.url = GURL("http://www.google.com/");
1315 request.load_flags = 0;
1316
[email protected]bb88e1d32013-05-03 23:11:071317 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361318 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501319 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171320
1321 MockRead data_reads[] = {
1322 MockRead("HTTP/1.0 200 OK\r\n"),
1323 MockRead("Connection: keep-alive\r\n"),
1324 MockRead("Content-Length: 100\r\n\r\n"),
1325 MockRead("hello"),
1326 MockRead(SYNCHRONOUS, 0),
1327 };
1328 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071329 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171330
1331 TestCompletionCallback callback;
1332
1333 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1334 EXPECT_EQ(ERR_IO_PENDING, rv);
1335
1336 rv = callback.WaitForResult();
1337 EXPECT_EQ(OK, rv);
1338
1339 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501340 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171341 if (rv == ERR_IO_PENDING)
1342 rv = callback.WaitForResult();
1343 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501344 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171345 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1346
1347 trans.reset();
[email protected]2da659e2013-05-23 20:51:341348 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171349 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1350}
1351
[email protected]23e482282013-06-14 16:08:021352TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171353 HttpRequestInfo request;
1354 request.method = "GET";
1355 request.url = GURL("http://www.google.com/");
1356 request.load_flags = 0;
1357
[email protected]bb88e1d32013-05-03 23:11:071358 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361359 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501360 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171361
1362 MockRead data_reads[] = {
1363 MockRead("HTTP/1.0 200 OK\r\n"),
1364 MockRead("Connection: keep-alive\r\n"),
1365 MockRead("Content-Length: 100\r\n\r\n"),
1366 MockRead(SYNCHRONOUS, 0),
1367 };
1368 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071369 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171370
1371 TestCompletionCallback callback;
1372
1373 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1374 EXPECT_EQ(ERR_IO_PENDING, rv);
1375
1376 rv = callback.WaitForResult();
1377 EXPECT_EQ(OK, rv);
1378
1379 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501380 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171381 if (rv == ERR_IO_PENDING)
1382 rv = callback.WaitForResult();
1383 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1384
1385 trans.reset();
[email protected]2da659e2013-05-23 20:51:341386 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171387 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1388}
1389
[email protected]0b0bf032010-09-21 18:08:501390// Test that we correctly reuse a keep-alive connection after not explicitly
1391// reading the body.
[email protected]23e482282013-06-14 16:08:021392TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131393 HttpRequestInfo request;
1394 request.method = "GET";
1395 request.url = GURL("http://www.foo.com/");
1396 request.load_flags = 0;
1397
[email protected]58e32bb2013-01-21 18:23:251398 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071399 session_deps_.net_log = &net_log;
1400 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271401
[email protected]0b0bf032010-09-21 18:08:501402 // Note that because all these reads happen in the same
1403 // StaticSocketDataProvider, it shows that the same socket is being reused for
1404 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131405 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501406 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1407 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131408 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501409 MockRead("HTTP/1.1 302 Found\r\n"
1410 "Content-Length: 0\r\n\r\n"),
1411 MockRead("HTTP/1.1 302 Found\r\n"
1412 "Content-Length: 5\r\n\r\n"
1413 "hello"),
1414 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1415 "Content-Length: 0\r\n\r\n"),
1416 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1417 "Content-Length: 5\r\n\r\n"
1418 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131419 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1420 MockRead("hello"),
1421 };
1422 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071423 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131424
1425 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061426 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131427 };
1428 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071429 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131430
[email protected]0b0bf032010-09-21 18:08:501431 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1432 std::string response_lines[kNumUnreadBodies];
1433
[email protected]58e32bb2013-01-21 18:23:251434 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501435 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411436 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131437
[email protected]262eec82013-03-19 21:01:361438 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501439 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131440
[email protected]49639fa2011-12-20 23:22:411441 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131442 EXPECT_EQ(ERR_IO_PENDING, rv);
1443
1444 rv = callback.WaitForResult();
1445 EXPECT_EQ(OK, rv);
1446
[email protected]58e32bb2013-01-21 18:23:251447 LoadTimingInfo load_timing_info;
1448 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1449 if (i == 0) {
1450 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1451 first_socket_log_id = load_timing_info.socket_log_id;
1452 } else {
1453 TestLoadTimingReused(load_timing_info);
1454 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1455 }
1456
[email protected]fc31d6a42010-06-24 18:05:131457 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501458 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131459
[email protected]90499482013-06-01 00:39:501460 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501461 response_lines[i] = response->headers->GetStatusLine();
1462
1463 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131464 }
[email protected]0b0bf032010-09-21 18:08:501465
1466 const char* const kStatusLines[] = {
1467 "HTTP/1.1 204 No Content",
1468 "HTTP/1.1 205 Reset Content",
1469 "HTTP/1.1 304 Not Modified",
1470 "HTTP/1.1 302 Found",
1471 "HTTP/1.1 302 Found",
1472 "HTTP/1.1 301 Moved Permanently",
1473 "HTTP/1.1 301 Moved Permanently",
1474 };
1475
1476 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1477 forgot_to_update_kStatusLines);
1478
1479 for (int i = 0; i < kNumUnreadBodies; ++i)
1480 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1481
[email protected]49639fa2011-12-20 23:22:411482 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361483 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501484 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411485 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501486 EXPECT_EQ(ERR_IO_PENDING, rv);
1487 rv = callback.WaitForResult();
1488 EXPECT_EQ(OK, rv);
1489 const HttpResponseInfo* response = trans->GetResponseInfo();
1490 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501491 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501492 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1493 std::string response_data;
1494 rv = ReadTransaction(trans.get(), &response_data);
1495 EXPECT_EQ(OK, rv);
1496 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131497}
1498
[email protected]038e9a32008-10-08 22:40:161499// Test the request-challenge-retry sequence for basic auth.
1500// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021501TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421502 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161503 request.method = "GET";
1504 request.url = GURL("http://www.google.com/");
1505 request.load_flags = 0;
1506
[email protected]58e32bb2013-01-21 18:23:251507 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071508 session_deps_.net_log = &log;
[email protected]cb9bf6ca2011-01-28 13:15:271509 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361510 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071511 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271512
[email protected]f9ee6b52008-11-08 06:46:231513 MockWrite data_writes1[] = {
1514 MockWrite("GET / HTTP/1.1\r\n"
1515 "Host: www.google.com\r\n"
1516 "Connection: keep-alive\r\n\r\n"),
1517 };
1518
[email protected]038e9a32008-10-08 22:40:161519 MockRead data_reads1[] = {
1520 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1521 // Give a couple authenticate options (only the middle one is actually
1522 // supported).
[email protected]22927ad2009-09-21 19:56:191523 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161524 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1525 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1526 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1527 // Large content-length -- won't matter, as connection will be reset.
1528 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061529 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161530 };
1531
1532 // After calling trans->RestartWithAuth(), this is the request we should
1533 // be issuing -- the final header line contains the credentials.
1534 MockWrite data_writes2[] = {
1535 MockWrite("GET / HTTP/1.1\r\n"
1536 "Host: www.google.com\r\n"
1537 "Connection: keep-alive\r\n"
1538 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1539 };
1540
1541 // Lastly, the server responds with the actual content.
1542 MockRead data_reads2[] = {
1543 MockRead("HTTP/1.0 200 OK\r\n"),
1544 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1545 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061546 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161547 };
1548
[email protected]31a2bfe2010-02-09 08:03:391549 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1550 data_writes1, arraysize(data_writes1));
1551 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1552 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071553 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161555
[email protected]49639fa2011-12-20 23:22:411556 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161557
[email protected]49639fa2011-12-20 23:22:411558 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421559 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161560
1561 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421562 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161563
[email protected]58e32bb2013-01-21 18:23:251564 LoadTimingInfo load_timing_info1;
1565 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1566 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1567
[email protected]1c773ea12009-04-28 19:58:421568 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501569 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041570 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161571
[email protected]49639fa2011-12-20 23:22:411572 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161573
[email protected]49639fa2011-12-20 23:22:411574 rv = trans->RestartWithAuth(
1575 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421576 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161577
1578 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421579 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161580
[email protected]58e32bb2013-01-21 18:23:251581 LoadTimingInfo load_timing_info2;
1582 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1583 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1584 // The load timing after restart should have a new socket ID, and times after
1585 // those of the first load timing.
1586 EXPECT_LE(load_timing_info1.receive_headers_end,
1587 load_timing_info2.connect_timing.connect_start);
1588 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1589
[email protected]038e9a32008-10-08 22:40:161590 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501591 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161592 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1593 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161594}
1595
[email protected]23e482282013-06-14 16:08:021596TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461597 HttpRequestInfo request;
1598 request.method = "GET";
1599 request.url = GURL("http://www.google.com/");
1600 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1601
[email protected]cb9bf6ca2011-01-28 13:15:271602 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361603 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071604 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271605
[email protected]861fcd52009-08-26 02:33:461606 MockWrite data_writes[] = {
1607 MockWrite("GET / HTTP/1.1\r\n"
1608 "Host: www.google.com\r\n"
1609 "Connection: keep-alive\r\n\r\n"),
1610 };
1611
1612 MockRead data_reads[] = {
1613 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1614 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1615 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1616 // Large content-length -- won't matter, as connection will be reset.
1617 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061618 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461619 };
1620
[email protected]31a2bfe2010-02-09 08:03:391621 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1622 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411624 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461625
[email protected]49639fa2011-12-20 23:22:411626 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461627 EXPECT_EQ(ERR_IO_PENDING, rv);
1628
1629 rv = callback.WaitForResult();
1630 EXPECT_EQ(0, rv);
1631
1632 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501633 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461634 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1635}
1636
[email protected]2d2697f92009-02-18 21:00:321637// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1638// connection.
[email protected]23e482282013-06-14 16:08:021639TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421640 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321641 request.method = "GET";
1642 request.url = GURL("http://www.google.com/");
1643 request.load_flags = 0;
1644
[email protected]58e32bb2013-01-21 18:23:251645 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071646 session_deps_.net_log = &log;
1647 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271648
[email protected]2d2697f92009-02-18 21:00:321649 MockWrite data_writes1[] = {
1650 MockWrite("GET / HTTP/1.1\r\n"
1651 "Host: www.google.com\r\n"
1652 "Connection: keep-alive\r\n\r\n"),
1653
1654 // After calling trans->RestartWithAuth(), this is the request we should
1655 // be issuing -- the final header line contains the credentials.
1656 MockWrite("GET / HTTP/1.1\r\n"
1657 "Host: www.google.com\r\n"
1658 "Connection: keep-alive\r\n"
1659 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1660 };
1661
1662 MockRead data_reads1[] = {
1663 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1664 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1665 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1666 MockRead("Content-Length: 14\r\n\r\n"),
1667 MockRead("Unauthorized\r\n"),
1668
1669 // Lastly, the server responds with the actual content.
1670 MockRead("HTTP/1.1 200 OK\r\n"),
1671 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501672 MockRead("Content-Length: 5\r\n\r\n"),
1673 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321674 };
1675
[email protected]2d0a4f92011-05-05 16:38:461676 // If there is a regression where we disconnect a Keep-Alive
1677 // connection during an auth roundtrip, we'll end up reading this.
1678 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061679 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461680 };
1681
[email protected]31a2bfe2010-02-09 08:03:391682 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1683 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461684 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1685 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071686 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1687 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321688
[email protected]49639fa2011-12-20 23:22:411689 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321690
[email protected]262eec82013-03-19 21:01:361691 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501692 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411693 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421694 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321695
1696 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421697 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321698
[email protected]58e32bb2013-01-21 18:23:251699 LoadTimingInfo load_timing_info1;
1700 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1701 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1702
[email protected]1c773ea12009-04-28 19:58:421703 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501704 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041705 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321706
[email protected]49639fa2011-12-20 23:22:411707 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321708
[email protected]49639fa2011-12-20 23:22:411709 rv = trans->RestartWithAuth(
1710 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421711 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321712
1713 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421714 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321715
[email protected]58e32bb2013-01-21 18:23:251716 LoadTimingInfo load_timing_info2;
1717 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1718 TestLoadTimingReused(load_timing_info2);
1719 // The load timing after restart should have the same socket ID, and times
1720 // those of the first load timing.
1721 EXPECT_LE(load_timing_info1.receive_headers_end,
1722 load_timing_info2.send_start);
1723 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1724
[email protected]2d2697f92009-02-18 21:00:321725 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501726 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321727 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501728 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321729}
1730
1731// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1732// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021733TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421734 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321735 request.method = "GET";
1736 request.url = GURL("http://www.google.com/");
1737 request.load_flags = 0;
1738
[email protected]bb88e1d32013-05-03 23:11:071739 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271740
[email protected]2d2697f92009-02-18 21:00:321741 MockWrite data_writes1[] = {
1742 MockWrite("GET / HTTP/1.1\r\n"
1743 "Host: www.google.com\r\n"
1744 "Connection: keep-alive\r\n\r\n"),
1745
1746 // After calling trans->RestartWithAuth(), this is the request we should
1747 // be issuing -- the final header line contains the credentials.
1748 MockWrite("GET / HTTP/1.1\r\n"
1749 "Host: www.google.com\r\n"
1750 "Connection: keep-alive\r\n"
1751 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1752 };
1753
[email protected]2d2697f92009-02-18 21:00:321754 MockRead data_reads1[] = {
1755 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1756 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311757 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321758
1759 // Lastly, the server responds with the actual content.
1760 MockRead("HTTP/1.1 200 OK\r\n"),
1761 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501762 MockRead("Content-Length: 5\r\n\r\n"),
1763 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321764 };
1765
[email protected]2d0a4f92011-05-05 16:38:461766 // An incorrect reconnect would cause this to be read.
1767 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061768 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461769 };
1770
[email protected]31a2bfe2010-02-09 08:03:391771 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1772 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461773 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1774 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071775 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1776 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321777
[email protected]49639fa2011-12-20 23:22:411778 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321779
[email protected]262eec82013-03-19 21:01:361780 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501781 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411782 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421783 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321784
1785 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421786 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321787
[email protected]1c773ea12009-04-28 19:58:421788 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501789 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041790 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321791
[email protected]49639fa2011-12-20 23:22:411792 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321793
[email protected]49639fa2011-12-20 23:22:411794 rv = trans->RestartWithAuth(
1795 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421796 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321797
1798 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421799 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321800
1801 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501802 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321803 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501804 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321805}
1806
1807// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1808// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:021809TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421810 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321811 request.method = "GET";
1812 request.url = GURL("http://www.google.com/");
1813 request.load_flags = 0;
1814
[email protected]bb88e1d32013-05-03 23:11:071815 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271816
[email protected]2d2697f92009-02-18 21:00:321817 MockWrite data_writes1[] = {
1818 MockWrite("GET / HTTP/1.1\r\n"
1819 "Host: www.google.com\r\n"
1820 "Connection: keep-alive\r\n\r\n"),
1821
1822 // After calling trans->RestartWithAuth(), this is the request we should
1823 // be issuing -- the final header line contains the credentials.
1824 MockWrite("GET / HTTP/1.1\r\n"
1825 "Host: www.google.com\r\n"
1826 "Connection: keep-alive\r\n"
1827 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1828 };
1829
1830 // Respond with 5 kb of response body.
1831 std::string large_body_string("Unauthorized");
1832 large_body_string.append(5 * 1024, ' ');
1833 large_body_string.append("\r\n");
1834
1835 MockRead data_reads1[] = {
1836 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1837 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1839 // 5134 = 12 + 5 * 1024 + 2
1840 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061841 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:321842
1843 // Lastly, the server responds with the actual content.
1844 MockRead("HTTP/1.1 200 OK\r\n"),
1845 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501846 MockRead("Content-Length: 5\r\n\r\n"),
1847 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321848 };
1849
[email protected]2d0a4f92011-05-05 16:38:461850 // An incorrect reconnect would cause this to be read.
1851 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061852 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461853 };
1854
[email protected]31a2bfe2010-02-09 08:03:391855 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1856 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461857 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1858 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071859 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1860 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321861
[email protected]49639fa2011-12-20 23:22:411862 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321863
[email protected]262eec82013-03-19 21:01:361864 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501865 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411866 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421867 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321868
1869 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421870 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321871
[email protected]1c773ea12009-04-28 19:58:421872 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501873 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041874 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321875
[email protected]49639fa2011-12-20 23:22:411876 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321877
[email protected]49639fa2011-12-20 23:22:411878 rv = trans->RestartWithAuth(
1879 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421880 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321881
1882 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421883 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321884
1885 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501886 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321887 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501888 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321889}
1890
1891// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:311892// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:021893TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:311894 HttpRequestInfo request;
1895 request.method = "GET";
1896 request.url = GURL("http://www.google.com/");
1897 request.load_flags = 0;
1898
[email protected]bb88e1d32013-05-03 23:11:071899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271900
[email protected]11203f012009-11-12 23:02:311901 MockWrite data_writes1[] = {
1902 MockWrite("GET / HTTP/1.1\r\n"
1903 "Host: www.google.com\r\n"
1904 "Connection: keep-alive\r\n\r\n"),
1905 // This simulates the seemingly successful write to a closed connection
1906 // if the bug is not fixed.
1907 MockWrite("GET / HTTP/1.1\r\n"
1908 "Host: www.google.com\r\n"
1909 "Connection: keep-alive\r\n"
1910 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1911 };
1912
1913 MockRead data_reads1[] = {
1914 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1915 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1916 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1917 MockRead("Content-Length: 14\r\n\r\n"),
1918 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:061919 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:311920 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:061921 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:311922 };
1923
1924 // After calling trans->RestartWithAuth(), this is the request we should
1925 // be issuing -- the final header line contains the credentials.
1926 MockWrite data_writes2[] = {
1927 MockWrite("GET / HTTP/1.1\r\n"
1928 "Host: www.google.com\r\n"
1929 "Connection: keep-alive\r\n"
1930 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1931 };
1932
1933 // Lastly, the server responds with the actual content.
1934 MockRead data_reads2[] = {
1935 MockRead("HTTP/1.1 200 OK\r\n"),
1936 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501937 MockRead("Content-Length: 5\r\n\r\n"),
1938 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:311939 };
1940
[email protected]31a2bfe2010-02-09 08:03:391941 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1942 data_writes1, arraysize(data_writes1));
1943 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1944 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1946 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:311947
[email protected]49639fa2011-12-20 23:22:411948 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:311949
[email protected]262eec82013-03-19 21:01:361950 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501951 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411952 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:311953 EXPECT_EQ(ERR_IO_PENDING, rv);
1954
1955 rv = callback1.WaitForResult();
1956 EXPECT_EQ(OK, rv);
1957
1958 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501959 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041960 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:311961
[email protected]49639fa2011-12-20 23:22:411962 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:311963
[email protected]49639fa2011-12-20 23:22:411964 rv = trans->RestartWithAuth(
1965 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:311966 EXPECT_EQ(ERR_IO_PENDING, rv);
1967
1968 rv = callback2.WaitForResult();
1969 EXPECT_EQ(OK, rv);
1970
1971 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501972 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:311973 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501974 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:311975}
1976
[email protected]394816e92010-08-03 07:38:591977// Test the request-challenge-retry sequence for basic auth, over a connection
1978// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:021979TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:591980 HttpRequestInfo request;
1981 request.method = "GET";
1982 request.url = GURL("https://www.google.com/");
1983 // when the no authentication data flag is set.
1984 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1985
[email protected]cb9bf6ca2011-01-28 13:15:271986 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:071987 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:201988 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:291989 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071990 session_deps_.net_log = log.bound().net_log();
1991 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271992
[email protected]394816e92010-08-03 07:38:591993 // Since we have proxy, should try to establish tunnel.
1994 MockWrite data_writes1[] = {
1995 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1996 "Host: www.google.com\r\n"
1997 "Proxy-Connection: keep-alive\r\n\r\n"),
1998
1999 // After calling trans->RestartWithAuth(), this is the request we should
2000 // be issuing -- the final header line contains the credentials.
2001 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2002 "Host: www.google.com\r\n"
2003 "Proxy-Connection: keep-alive\r\n"
2004 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2005
2006 MockWrite("GET / HTTP/1.1\r\n"
2007 "Host: www.google.com\r\n"
2008 "Connection: keep-alive\r\n\r\n"),
2009 };
2010
2011 // The proxy responds to the connect with a 407, using a persistent
2012 // connection.
2013 MockRead data_reads1[] = {
2014 // No credentials.
2015 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2016 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2017 MockRead("Proxy-Connection: close\r\n\r\n"),
2018
2019 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2020
2021 MockRead("HTTP/1.1 200 OK\r\n"),
2022 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502023 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062024 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592025 };
2026
2027 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2028 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072029 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062030 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072031 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592032
[email protected]49639fa2011-12-20 23:22:412033 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592034
[email protected]262eec82013-03-19 21:01:362035 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502036 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502037
[email protected]49639fa2011-12-20 23:22:412038 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592039 EXPECT_EQ(ERR_IO_PENDING, rv);
2040
2041 rv = callback1.WaitForResult();
2042 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572043 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402044 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592045 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402046 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592047 NetLog::PHASE_NONE);
2048 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402049 entries, pos,
[email protected]394816e92010-08-03 07:38:592050 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2051 NetLog::PHASE_NONE);
2052
2053 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502054 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502055 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592056 EXPECT_EQ(407, response->headers->response_code());
2057 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042058 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592059
[email protected]029c83b62013-01-24 05:28:202060 LoadTimingInfo load_timing_info;
2061 // CONNECT requests and responses are handled at the connect job level, so
2062 // the transaction does not yet have a connection.
2063 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2064
[email protected]49639fa2011-12-20 23:22:412065 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592066
[email protected]49639fa2011-12-20 23:22:412067 rv = trans->RestartWithAuth(
2068 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592069 EXPECT_EQ(ERR_IO_PENDING, rv);
2070
2071 rv = callback2.WaitForResult();
2072 EXPECT_EQ(OK, rv);
2073
2074 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502075 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592076
2077 EXPECT_TRUE(response->headers->IsKeepAlive());
2078 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502079 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592080 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2081
2082 // The password prompt info should not be set.
2083 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502084
[email protected]029c83b62013-01-24 05:28:202085 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2086 TestLoadTimingNotReusedWithPac(load_timing_info,
2087 CONNECT_TIMING_HAS_SSL_TIMES);
2088
[email protected]0b0bf032010-09-21 18:08:502089 trans.reset();
[email protected]102e27c2011-02-23 01:01:312090 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592091}
2092
[email protected]11203f012009-11-12 23:02:312093// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322094// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022095TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272096 HttpRequestInfo request;
2097 request.method = "GET";
2098 request.url = GURL("https://www.google.com/");
2099 // Ensure that proxy authentication is attempted even
2100 // when the no authentication data flag is set.
2101 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2102
[email protected]2d2697f92009-02-18 21:00:322103 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072104 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292105 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072106 session_deps_.net_log = log.bound().net_log();
2107 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322108
[email protected]262eec82013-03-19 21:01:362109 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502110 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322111
[email protected]2d2697f92009-02-18 21:00:322112 // Since we have proxy, should try to establish tunnel.
2113 MockWrite data_writes1[] = {
2114 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452115 "Host: www.google.com\r\n"
2116 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322117
2118 // After calling trans->RestartWithAuth(), this is the request we should
2119 // be issuing -- the final header line contains the credentials.
2120 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2121 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452122 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322123 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2124 };
2125
2126 // The proxy responds to the connect with a 407, using a persistent
2127 // connection.
2128 MockRead data_reads1[] = {
2129 // No credentials.
2130 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2131 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2132 MockRead("Content-Length: 10\r\n\r\n"),
2133 MockRead("0123456789"),
2134
2135 // Wrong credentials (wrong password).
2136 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2137 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2138 MockRead("Content-Length: 10\r\n\r\n"),
2139 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062140 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322141 };
2142
[email protected]31a2bfe2010-02-09 08:03:392143 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2144 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072145 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322146
[email protected]49639fa2011-12-20 23:22:412147 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322148
[email protected]49639fa2011-12-20 23:22:412149 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422150 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322151
2152 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422153 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572154 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402155 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392156 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402157 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392158 NetLog::PHASE_NONE);
2159 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402160 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392161 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2162 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322163
[email protected]1c773ea12009-04-28 19:58:422164 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502165 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502166 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322167 EXPECT_TRUE(response->headers->IsKeepAlive());
2168 EXPECT_EQ(407, response->headers->response_code());
2169 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422170 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042171 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322172
[email protected]49639fa2011-12-20 23:22:412173 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322174
2175 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412176 rv = trans->RestartWithAuth(
2177 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422178 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322179
2180 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422181 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322182
2183 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502184 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502185 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322186 EXPECT_TRUE(response->headers->IsKeepAlive());
2187 EXPECT_EQ(407, response->headers->response_code());
2188 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422189 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042190 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132191
[email protected]e60e47a2010-07-14 03:37:182192 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2193 // out of scope.
[email protected]102e27c2011-02-23 01:01:312194 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322195}
2196
[email protected]a8e9b162009-03-12 00:06:442197// Test that we don't read the response body when we fail to establish a tunnel,
2198// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022199TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272200 HttpRequestInfo request;
2201 request.method = "GET";
2202 request.url = GURL("https://www.google.com/");
2203 request.load_flags = 0;
2204
[email protected]a8e9b162009-03-12 00:06:442205 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072206 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442207
[email protected]bb88e1d32013-05-03 23:11:072208 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442209
[email protected]262eec82013-03-19 21:01:362210 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442212
[email protected]a8e9b162009-03-12 00:06:442213 // Since we have proxy, should try to establish tunnel.
2214 MockWrite data_writes[] = {
2215 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452216 "Host: www.google.com\r\n"
2217 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442218 };
2219
2220 // The proxy responds to the connect with a 407.
2221 MockRead data_reads[] = {
2222 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2223 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2224 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062225 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442226 };
2227
[email protected]31a2bfe2010-02-09 08:03:392228 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2229 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072230 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442231
[email protected]49639fa2011-12-20 23:22:412232 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442233
[email protected]49639fa2011-12-20 23:22:412234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422235 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442236
2237 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422238 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442239
[email protected]1c773ea12009-04-28 19:58:422240 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502241 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442242
2243 EXPECT_TRUE(response->headers->IsKeepAlive());
2244 EXPECT_EQ(407, response->headers->response_code());
2245 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422246 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442247
2248 std::string response_data;
2249 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422250 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182251
2252 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312253 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442254}
2255
[email protected]8fdbcd22010-05-05 02:54:522256// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2257// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022258TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522259 HttpRequestInfo request;
2260 request.method = "GET";
2261 request.url = GURL("http://www.google.com/");
2262 request.load_flags = 0;
2263
[email protected]cb9bf6ca2011-01-28 13:15:272264 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]cb9bf6ca2011-01-28 13:15:272265 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:362266 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:072267 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:272268
[email protected]8fdbcd22010-05-05 02:54:522269 MockWrite data_writes1[] = {
2270 MockWrite("GET / HTTP/1.1\r\n"
2271 "Host: www.google.com\r\n"
2272 "Connection: keep-alive\r\n\r\n"),
2273 };
2274
2275 MockRead data_reads1[] = {
2276 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2277 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2278 // Large content-length -- won't matter, as connection will be reset.
2279 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062280 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522281 };
2282
2283 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2284 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072285 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522286
[email protected]49639fa2011-12-20 23:22:412287 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522288
[email protected]49639fa2011-12-20 23:22:412289 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522290 EXPECT_EQ(ERR_IO_PENDING, rv);
2291
2292 rv = callback.WaitForResult();
2293 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2294}
2295
[email protected]7a67a8152010-11-05 18:31:102296// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2297// through a non-authenticating proxy. The request should fail with
2298// ERR_UNEXPECTED_PROXY_AUTH.
2299// Note that it is impossible to detect if an HTTP server returns a 407 through
2300// a non-authenticating proxy - there is nothing to indicate whether the
2301// response came from the proxy or the server, so it is treated as if the proxy
2302// issued the challenge.
[email protected]23e482282013-06-14 16:08:022303TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232304 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272305 HttpRequestInfo request;
2306 request.method = "GET";
2307 request.url = GURL("https://www.google.com/");
2308
[email protected]bb88e1d32013-05-03 23:11:072309 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292310 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072311 session_deps_.net_log = log.bound().net_log();
2312 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102313
[email protected]7a67a8152010-11-05 18:31:102314 // Since we have proxy, should try to establish tunnel.
2315 MockWrite data_writes1[] = {
2316 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2317 "Host: www.google.com\r\n"
2318 "Proxy-Connection: keep-alive\r\n\r\n"),
2319
2320 MockWrite("GET / HTTP/1.1\r\n"
2321 "Host: www.google.com\r\n"
2322 "Connection: keep-alive\r\n\r\n"),
2323 };
2324
2325 MockRead data_reads1[] = {
2326 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2327
2328 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2329 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2330 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062331 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102332 };
2333
2334 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2335 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072336 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062337 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102339
[email protected]49639fa2011-12-20 23:22:412340 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102341
[email protected]262eec82013-03-19 21:01:362342 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502343 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102344
[email protected]49639fa2011-12-20 23:22:412345 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102346 EXPECT_EQ(ERR_IO_PENDING, rv);
2347
2348 rv = callback1.WaitForResult();
2349 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572350 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402351 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102352 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402353 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102354 NetLog::PHASE_NONE);
2355 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402356 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102357 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2358 NetLog::PHASE_NONE);
2359}
[email protected]2df19bb2010-08-25 20:13:462360
[email protected]029c83b62013-01-24 05:28:202361// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022362TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202363 HttpRequestInfo request1;
2364 request1.method = "GET";
2365 request1.url = GURL("https://www.google.com/1");
2366
2367 HttpRequestInfo request2;
2368 request2.method = "GET";
2369 request2.url = GURL("https://www.google.com/2");
2370
2371 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072372 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202373 ProxyService::CreateFixed("PROXY myproxy:70"));
2374 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072375 session_deps_.net_log = log.bound().net_log();
2376 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202377
2378 // Since we have proxy, should try to establish tunnel.
2379 MockWrite data_writes1[] = {
2380 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2381 "Host: www.google.com\r\n"
2382 "Proxy-Connection: keep-alive\r\n\r\n"),
2383
2384 MockWrite("GET /1 HTTP/1.1\r\n"
2385 "Host: www.google.com\r\n"
2386 "Connection: keep-alive\r\n\r\n"),
2387
2388 MockWrite("GET /2 HTTP/1.1\r\n"
2389 "Host: www.google.com\r\n"
2390 "Connection: keep-alive\r\n\r\n"),
2391 };
2392
2393 // The proxy responds to the connect with a 407, using a persistent
2394 // connection.
2395 MockRead data_reads1[] = {
2396 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2397
2398 MockRead("HTTP/1.1 200 OK\r\n"),
2399 MockRead("Content-Length: 1\r\n\r\n"),
2400 MockRead(SYNCHRONOUS, "1"),
2401
2402 MockRead("HTTP/1.1 200 OK\r\n"),
2403 MockRead("Content-Length: 2\r\n\r\n"),
2404 MockRead(SYNCHRONOUS, "22"),
2405 };
2406
2407 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2408 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072409 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202410 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072411 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202412
2413 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362414 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202416
2417 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2418 EXPECT_EQ(ERR_IO_PENDING, rv);
2419
2420 rv = callback1.WaitForResult();
2421 EXPECT_EQ(OK, rv);
2422
2423 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2424 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502425 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202426 EXPECT_EQ(1, response1->headers->GetContentLength());
2427
2428 LoadTimingInfo load_timing_info1;
2429 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2430 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2431
2432 trans1.reset();
2433
2434 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362435 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202437
2438 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2439 EXPECT_EQ(ERR_IO_PENDING, rv);
2440
2441 rv = callback2.WaitForResult();
2442 EXPECT_EQ(OK, rv);
2443
2444 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2445 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502446 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202447 EXPECT_EQ(2, response2->headers->GetContentLength());
2448
2449 LoadTimingInfo load_timing_info2;
2450 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2451 TestLoadTimingReused(load_timing_info2);
2452
2453 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2454
2455 trans2.reset();
2456 session->CloseAllConnections();
2457}
2458
2459// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022460TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202461 HttpRequestInfo request1;
2462 request1.method = "GET";
2463 request1.url = GURL("https://www.google.com/1");
2464
2465 HttpRequestInfo request2;
2466 request2.method = "GET";
2467 request2.url = GURL("https://www.google.com/2");
2468
2469 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072470 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202471 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2472 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072473 session_deps_.net_log = log.bound().net_log();
2474 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202475
2476 // Since we have proxy, should try to establish tunnel.
2477 MockWrite data_writes1[] = {
2478 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2479 "Host: www.google.com\r\n"
2480 "Proxy-Connection: keep-alive\r\n\r\n"),
2481
2482 MockWrite("GET /1 HTTP/1.1\r\n"
2483 "Host: www.google.com\r\n"
2484 "Connection: keep-alive\r\n\r\n"),
2485
2486 MockWrite("GET /2 HTTP/1.1\r\n"
2487 "Host: www.google.com\r\n"
2488 "Connection: keep-alive\r\n\r\n"),
2489 };
2490
2491 // The proxy responds to the connect with a 407, using a persistent
2492 // connection.
2493 MockRead data_reads1[] = {
2494 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2495
2496 MockRead("HTTP/1.1 200 OK\r\n"),
2497 MockRead("Content-Length: 1\r\n\r\n"),
2498 MockRead(SYNCHRONOUS, "1"),
2499
2500 MockRead("HTTP/1.1 200 OK\r\n"),
2501 MockRead("Content-Length: 2\r\n\r\n"),
2502 MockRead(SYNCHRONOUS, "22"),
2503 };
2504
2505 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2506 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072507 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202508 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072509 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202510
2511 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362512 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202514
2515 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2516 EXPECT_EQ(ERR_IO_PENDING, rv);
2517
2518 rv = callback1.WaitForResult();
2519 EXPECT_EQ(OK, rv);
2520
2521 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2522 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502523 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202524 EXPECT_EQ(1, response1->headers->GetContentLength());
2525
2526 LoadTimingInfo load_timing_info1;
2527 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2528 TestLoadTimingNotReusedWithPac(load_timing_info1,
2529 CONNECT_TIMING_HAS_SSL_TIMES);
2530
2531 trans1.reset();
2532
2533 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362534 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502535 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202536
2537 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2538 EXPECT_EQ(ERR_IO_PENDING, rv);
2539
2540 rv = callback2.WaitForResult();
2541 EXPECT_EQ(OK, rv);
2542
2543 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2544 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502545 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202546 EXPECT_EQ(2, response2->headers->GetContentLength());
2547
2548 LoadTimingInfo load_timing_info2;
2549 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2550 TestLoadTimingReusedWithPac(load_timing_info2);
2551
2552 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2553
2554 trans2.reset();
2555 session->CloseAllConnections();
2556}
2557
[email protected]2df19bb2010-08-25 20:13:462558// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022559TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272560 HttpRequestInfo request;
2561 request.method = "GET";
2562 request.url = GURL("http://www.google.com/");
2563
[email protected]2df19bb2010-08-25 20:13:462564 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072565 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112566 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292567 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072568 session_deps_.net_log = log.bound().net_log();
2569 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462570
[email protected]2df19bb2010-08-25 20:13:462571 // Since we have proxy, should use full url
2572 MockWrite data_writes1[] = {
2573 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2574 "Host: www.google.com\r\n"
2575 "Proxy-Connection: keep-alive\r\n\r\n"),
2576 };
2577
2578 MockRead data_reads1[] = {
2579 MockRead("HTTP/1.1 200 OK\r\n"),
2580 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2581 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062582 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462583 };
2584
2585 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2586 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072587 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062588 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462590
[email protected]49639fa2011-12-20 23:22:412591 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462592
[email protected]262eec82013-03-19 21:01:362593 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502595
[email protected]49639fa2011-12-20 23:22:412596 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462597 EXPECT_EQ(ERR_IO_PENDING, rv);
2598
2599 rv = callback1.WaitForResult();
2600 EXPECT_EQ(OK, rv);
2601
[email protected]58e32bb2013-01-21 18:23:252602 LoadTimingInfo load_timing_info;
2603 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2604 TestLoadTimingNotReused(load_timing_info,
2605 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2606
[email protected]2df19bb2010-08-25 20:13:462607 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502608 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462609
2610 EXPECT_TRUE(response->headers->IsKeepAlive());
2611 EXPECT_EQ(200, response->headers->response_code());
2612 EXPECT_EQ(100, response->headers->GetContentLength());
2613 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2614
2615 // The password prompt info should not be set.
2616 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2617}
2618
[email protected]7642b5ae2010-09-01 20:55:172619// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022620TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272621 HttpRequestInfo request;
2622 request.method = "GET";
2623 request.url = GURL("http://www.google.com/");
2624 request.load_flags = 0;
2625
[email protected]7642b5ae2010-09-01 20:55:172626 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072627 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112628 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292629 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072630 session_deps_.net_log = log.bound().net_log();
2631 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172632
[email protected]7642b5ae2010-09-01 20:55:172633 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462634 scoped_ptr<SpdyFrame> req(
2635 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172636 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2637
[email protected]23e482282013-06-14 16:08:022638 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2639 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172640 MockRead spdy_reads[] = {
2641 CreateMockRead(*resp),
2642 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062643 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172644 };
2645
[email protected]dd54bd82012-07-19 23:44:572646 DelayedSocketData spdy_data(
2647 1, // wait for one write to finish before reading.
2648 spdy_reads, arraysize(spdy_reads),
2649 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072650 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172651
[email protected]8ddf8322012-02-23 18:08:062652 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022653 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072654 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172655
[email protected]49639fa2011-12-20 23:22:412656 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172657
[email protected]262eec82013-03-19 21:01:362658 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502659 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502660
[email protected]49639fa2011-12-20 23:22:412661 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172662 EXPECT_EQ(ERR_IO_PENDING, rv);
2663
2664 rv = callback1.WaitForResult();
2665 EXPECT_EQ(OK, rv);
2666
[email protected]58e32bb2013-01-21 18:23:252667 LoadTimingInfo load_timing_info;
2668 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2669 TestLoadTimingNotReused(load_timing_info,
2670 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2671
[email protected]7642b5ae2010-09-01 20:55:172672 const HttpResponseInfo* response = trans->GetResponseInfo();
2673 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502674 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172675 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2676
2677 std::string response_data;
2678 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232679 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172680}
2681
[email protected]dc7bd1c52010-11-12 00:01:132682// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022683TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272684 HttpRequestInfo request;
2685 request.method = "GET";
2686 request.url = GURL("http://www.google.com/");
2687 request.load_flags = 0;
2688
[email protected]79cb5c12011-09-12 13:12:042689 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072690 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042691 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292692 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072693 session_deps_.net_log = log.bound().net_log();
2694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132695
[email protected]dc7bd1c52010-11-12 00:01:132696 // The first request will be a bare GET, the second request will be a
2697 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192698 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462699 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132700 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462701 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132702 };
[email protected]ff98d7f02012-03-22 21:44:192703 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462704 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2705 arraysize(kExtraAuthorizationHeaders) / 2,
2706 false,
2707 3,
2708 LOWEST,
2709 false));
[email protected]dc7bd1c52010-11-12 00:01:132710 MockWrite spdy_writes[] = {
2711 CreateMockWrite(*req_get, 1),
2712 CreateMockWrite(*req_get_authorization, 4),
2713 };
2714
2715 // The first response is a 407 proxy authentication challenge, and the second
2716 // response will be a 200 response since the second request includes a valid
2717 // Authorization header.
2718 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462719 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132720 };
[email protected]ff98d7f02012-03-22 21:44:192721 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022722 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132723 "407 Proxy Authentication Required",
2724 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2725 1));
[email protected]ff98d7f02012-03-22 21:44:192726 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022727 spdy_util_.ConstructSpdyBodyFrame(1, true));
2728 scoped_ptr<SpdyFrame> resp_data(
2729 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2730 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132731 MockRead spdy_reads[] = {
2732 CreateMockRead(*resp_authentication, 2),
2733 CreateMockRead(*body_authentication, 3),
2734 CreateMockRead(*resp_data, 5),
2735 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:062736 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:132737 };
2738
[email protected]dd54bd82012-07-19 23:44:572739 OrderedSocketData data(
2740 spdy_reads, arraysize(spdy_reads),
2741 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072742 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:132743
[email protected]8ddf8322012-02-23 18:08:062744 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022745 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072746 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:132747
[email protected]49639fa2011-12-20 23:22:412748 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132749
[email protected]262eec82013-03-19 21:01:362750 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:132752
[email protected]49639fa2011-12-20 23:22:412753 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:132754 EXPECT_EQ(ERR_IO_PENDING, rv);
2755
2756 rv = callback1.WaitForResult();
2757 EXPECT_EQ(OK, rv);
2758
2759 const HttpResponseInfo* const response = trans->GetResponseInfo();
2760
2761 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502762 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132763 EXPECT_EQ(407, response->headers->response_code());
2764 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042765 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132766
[email protected]49639fa2011-12-20 23:22:412767 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132768
[email protected]49639fa2011-12-20 23:22:412769 rv = trans->RestartWithAuth(
2770 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:132771 EXPECT_EQ(ERR_IO_PENDING, rv);
2772
2773 rv = callback2.WaitForResult();
2774 EXPECT_EQ(OK, rv);
2775
2776 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2777
2778 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:502779 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132780 EXPECT_EQ(200, response_restart->headers->response_code());
2781 // The password prompt info should not be set.
2782 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2783}
2784
[email protected]d9da5fe2010-10-13 22:37:162785// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:022786TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272787 HttpRequestInfo request;
2788 request.method = "GET";
2789 request.url = GURL("https://www.google.com/");
2790 request.load_flags = 0;
2791
[email protected]d9da5fe2010-10-13 22:37:162792 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072793 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112794 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292795 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072796 session_deps_.net_log = log.bound().net_log();
2797 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162798
[email protected]262eec82013-03-19 21:01:362799 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502800 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162801
[email protected]d9da5fe2010-10-13 22:37:162802 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542803 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2804 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162805 // fetch https://www.google.com/ via HTTP
2806
2807 const char get[] = "GET / HTTP/1.1\r\n"
2808 "Host: www.google.com\r\n"
2809 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192810 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:022811 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2812 scoped_ptr<SpdyFrame> conn_resp(
2813 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162814 const char resp[] = "HTTP/1.1 200 OK\r\n"
2815 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192816 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022817 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:192818 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:022819 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:192820 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:202821 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:042822
2823 MockWrite spdy_writes[] = {
2824 CreateMockWrite(*connect, 1),
2825 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:462826 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:042827 };
2828
[email protected]d9da5fe2010-10-13 22:37:162829 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062830 CreateMockRead(*conn_resp, 2, ASYNC),
2831 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2832 CreateMockRead(*wrapped_body, 6, ASYNC),
2833 CreateMockRead(*wrapped_body, 7, ASYNC),
2834 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162835 };
2836
[email protected]dd54bd82012-07-19 23:44:572837 OrderedSocketData spdy_data(
2838 spdy_reads, arraysize(spdy_reads),
2839 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072840 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162841
[email protected]8ddf8322012-02-23 18:08:062842 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022843 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072844 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062845 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:162846 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:462847 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:072848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162849
[email protected]49639fa2011-12-20 23:22:412850 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162851
[email protected]49639fa2011-12-20 23:22:412852 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162853 EXPECT_EQ(ERR_IO_PENDING, rv);
2854
2855 rv = callback1.WaitForResult();
2856 EXPECT_EQ(OK, rv);
2857
[email protected]58e32bb2013-01-21 18:23:252858 LoadTimingInfo load_timing_info;
2859 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2860 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2861
[email protected]d9da5fe2010-10-13 22:37:162862 const HttpResponseInfo* response = trans->GetResponseInfo();
2863 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502864 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162865 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2866
2867 std::string response_data;
2868 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2869 EXPECT_EQ("1234567890", response_data);
2870}
2871
2872// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:022873TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:272874 HttpRequestInfo request;
2875 request.method = "GET";
2876 request.url = GURL("https://www.google.com/");
2877 request.load_flags = 0;
2878
[email protected]d9da5fe2010-10-13 22:37:162879 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072880 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112881 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292882 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072883 session_deps_.net_log = log.bound().net_log();
2884 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162885
[email protected]262eec82013-03-19 21:01:362886 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162888
[email protected]d9da5fe2010-10-13 22:37:162889 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542890 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2891 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162892 // fetch https://www.google.com/ via SPDY
2893 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:462894 scoped_ptr<SpdyFrame> get(
2895 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:022896 scoped_ptr<SpdyFrame> wrapped_get(
2897 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
2898 scoped_ptr<SpdyFrame> conn_resp(
2899 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2900 scoped_ptr<SpdyFrame> get_resp(
2901 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:192902 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022903 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
2904 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2905 scoped_ptr<SpdyFrame> wrapped_body(
2906 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:192907 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:202908 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:192909 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:202910 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:042911
2912 MockWrite spdy_writes[] = {
2913 CreateMockWrite(*connect, 1),
2914 CreateMockWrite(*wrapped_get, 3),
2915 CreateMockWrite(*window_update_get_resp, 5),
2916 CreateMockWrite(*window_update_body, 7),
2917 };
2918
[email protected]d9da5fe2010-10-13 22:37:162919 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062920 CreateMockRead(*conn_resp, 2, ASYNC),
2921 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2922 CreateMockRead(*wrapped_body, 6, ASYNC),
2923 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162924 };
2925
[email protected]dd54bd82012-07-19 23:44:572926 OrderedSocketData spdy_data(
2927 spdy_reads, arraysize(spdy_reads),
2928 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072929 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162930
[email protected]8ddf8322012-02-23 18:08:062931 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022932 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062934 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022935 ssl2.SetNextProto(GetParam());
2936 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:072937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162938
[email protected]49639fa2011-12-20 23:22:412939 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162940
[email protected]49639fa2011-12-20 23:22:412941 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162942 EXPECT_EQ(ERR_IO_PENDING, rv);
2943
2944 rv = callback1.WaitForResult();
2945 EXPECT_EQ(OK, rv);
2946
[email protected]58e32bb2013-01-21 18:23:252947 LoadTimingInfo load_timing_info;
2948 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2949 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2950
[email protected]d9da5fe2010-10-13 22:37:162951 const HttpResponseInfo* response = trans->GetResponseInfo();
2952 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502953 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162954 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2955
2956 std::string response_data;
2957 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232958 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:162959}
2960
2961// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022962TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:272963 HttpRequestInfo request;
2964 request.method = "GET";
2965 request.url = GURL("https://www.google.com/");
2966 request.load_flags = 0;
2967
[email protected]d9da5fe2010-10-13 22:37:162968 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072969 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112970 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292971 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072972 session_deps_.net_log = log.bound().net_log();
2973 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162974
[email protected]262eec82013-03-19 21:01:362975 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162977
[email protected]d9da5fe2010-10-13 22:37:162978 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542979 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2980 LOWEST));
[email protected]c10b20852013-05-15 21:29:202981 scoped_ptr<SpdyFrame> get(
2982 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:162983
2984 MockWrite spdy_writes[] = {
2985 CreateMockWrite(*connect, 1),
2986 CreateMockWrite(*get, 3),
2987 };
2988
[email protected]23e482282013-06-14 16:08:022989 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
2990 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:162991 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062992 CreateMockRead(*resp, 2, ASYNC),
2993 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:162994 };
2995
[email protected]dd54bd82012-07-19 23:44:572996 OrderedSocketData spdy_data(
2997 spdy_reads, arraysize(spdy_reads),
2998 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072999 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163000
[email protected]8ddf8322012-02-23 18:08:063001 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023002 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073003 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063004 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023005 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073006 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163007
[email protected]49639fa2011-12-20 23:22:413008 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163009
[email protected]49639fa2011-12-20 23:22:413010 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163011 EXPECT_EQ(ERR_IO_PENDING, rv);
3012
3013 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173014 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163015
[email protected]4eddbc732012-08-09 05:40:173016 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163017}
3018
[email protected]f6c63db52013-02-02 00:35:223019// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3020// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023021TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223022 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3023 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073024 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223025 "https://proxy:70"));
3026 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073027 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223028 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073029 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223030
3031 HttpRequestInfo request1;
3032 request1.method = "GET";
3033 request1.url = GURL("https://www.google.com/");
3034 request1.load_flags = 0;
3035
3036 HttpRequestInfo request2;
3037 request2.method = "GET";
3038 request2.url = GURL("https://news.google.com/");
3039 request2.load_flags = 0;
3040
3041 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543042 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3043 LOWEST));
[email protected]23e482282013-06-14 16:08:023044 scoped_ptr<SpdyFrame> conn_resp1(
3045 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223046
3047 // Fetch https://www.google.com/ via HTTP.
3048 const char get1[] = "GET / HTTP/1.1\r\n"
3049 "Host: www.google.com\r\n"
3050 "Connection: keep-alive\r\n\r\n";
3051 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023052 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223053 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3054 "Content-Length: 1\r\n\r\n";
3055 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023056 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3057 scoped_ptr<SpdyFrame> wrapped_body1(
3058 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223059 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203060 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223061
3062 // CONNECT to news.google.com:443 via SPDY.
3063 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023064 spdy_util_.GetMethodKey(), "CONNECT",
3065 spdy_util_.GetPathKey(), "news.google.com:443",
3066 spdy_util_.GetHostKey(), "news.google.com",
3067 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223068 };
3069 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233070 spdy_util_.ConstructSpdyControlFrame(NULL,
3071 0,
3072 /*compressed*/ false,
3073 3,
3074 LOWEST,
3075 SYN_STREAM,
3076 CONTROL_FLAG_NONE,
3077 kConnectHeaders2,
3078 arraysize(kConnectHeaders2),
3079 0));
[email protected]23e482282013-06-14 16:08:023080 scoped_ptr<SpdyFrame> conn_resp2(
3081 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223082
3083 // Fetch https://news.google.com/ via HTTP.
3084 const char get2[] = "GET / HTTP/1.1\r\n"
3085 "Host: news.google.com\r\n"
3086 "Connection: keep-alive\r\n\r\n";
3087 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023088 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223089 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3090 "Content-Length: 2\r\n\r\n";
3091 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023092 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223093 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023094 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223095
3096 MockWrite spdy_writes[] = {
3097 CreateMockWrite(*connect1, 0),
3098 CreateMockWrite(*wrapped_get1, 2),
3099 CreateMockWrite(*connect2, 5),
3100 CreateMockWrite(*wrapped_get2, 7),
3101 };
3102
3103 MockRead spdy_reads[] = {
3104 CreateMockRead(*conn_resp1, 1, ASYNC),
3105 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3106 CreateMockRead(*wrapped_body1, 4, ASYNC),
3107 CreateMockRead(*conn_resp2, 6, ASYNC),
3108 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3109 CreateMockRead(*wrapped_body2, 9, ASYNC),
3110 MockRead(ASYNC, 0, 10),
3111 };
3112
3113 DeterministicSocketData spdy_data(
3114 spdy_reads, arraysize(spdy_reads),
3115 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073116 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223117
3118 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023119 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073120 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223121 SSLSocketDataProvider ssl2(ASYNC, OK);
3122 ssl2.was_npn_negotiated = false;
3123 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073124 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223125 SSLSocketDataProvider ssl3(ASYNC, OK);
3126 ssl3.was_npn_negotiated = false;
3127 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073128 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223129
3130 TestCompletionCallback callback;
3131
[email protected]262eec82013-03-19 21:01:363132 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223134 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3135 EXPECT_EQ(ERR_IO_PENDING, rv);
3136 // The first connect and request, each of their responses, and the body.
3137 spdy_data.RunFor(5);
3138
3139 rv = callback.WaitForResult();
3140 EXPECT_EQ(OK, rv);
3141
3142 LoadTimingInfo load_timing_info;
3143 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3144 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3145
3146 const HttpResponseInfo* response = trans->GetResponseInfo();
3147 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503148 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223149 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3150
3151 std::string response_data;
3152 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503153 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223154
[email protected]262eec82013-03-19 21:01:363155 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503156 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223157 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3158 EXPECT_EQ(ERR_IO_PENDING, rv);
3159
3160 // The second connect and request, each of their responses, and the body.
3161 spdy_data.RunFor(5);
3162 rv = callback.WaitForResult();
3163 EXPECT_EQ(OK, rv);
3164
3165 LoadTimingInfo load_timing_info2;
3166 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3167 // Even though the SPDY connection is reused, a new tunnelled connection has
3168 // to be created, so the socket's load timing looks like a fresh connection.
3169 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3170
3171 // The requests should have different IDs, since they each are using their own
3172 // separate stream.
3173 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3174
[email protected]90499482013-06-01 00:39:503175 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223176}
3177
3178// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3179// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023180TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223181 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3182 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073183 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223184 "https://proxy:70"));
3185 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073186 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223187 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073188 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223189
3190 HttpRequestInfo request1;
3191 request1.method = "GET";
3192 request1.url = GURL("https://www.google.com/");
3193 request1.load_flags = 0;
3194
3195 HttpRequestInfo request2;
3196 request2.method = "GET";
3197 request2.url = GURL("https://www.google.com/2");
3198 request2.load_flags = 0;
3199
3200 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543201 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3202 LOWEST));
[email protected]23e482282013-06-14 16:08:023203 scoped_ptr<SpdyFrame> conn_resp1(
3204 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223205
3206 // Fetch https://www.google.com/ via HTTP.
3207 const char get1[] = "GET / HTTP/1.1\r\n"
3208 "Host: www.google.com\r\n"
3209 "Connection: keep-alive\r\n\r\n";
3210 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023211 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223212 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3213 "Content-Length: 1\r\n\r\n";
3214 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023215 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3216 scoped_ptr<SpdyFrame> wrapped_body1(
3217 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223218 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203219 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223220
3221 // Fetch https://www.google.com/2 via HTTP.
3222 const char get2[] = "GET /2 HTTP/1.1\r\n"
3223 "Host: www.google.com\r\n"
3224 "Connection: keep-alive\r\n\r\n";
3225 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023226 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223227 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3228 "Content-Length: 2\r\n\r\n";
3229 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023230 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223231 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023232 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223233
3234 MockWrite spdy_writes[] = {
3235 CreateMockWrite(*connect1, 0),
3236 CreateMockWrite(*wrapped_get1, 2),
3237 CreateMockWrite(*wrapped_get2, 5),
3238 };
3239
3240 MockRead spdy_reads[] = {
3241 CreateMockRead(*conn_resp1, 1, ASYNC),
3242 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3243 CreateMockRead(*wrapped_body1, 4, ASYNC),
3244 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3245 CreateMockRead(*wrapped_body2, 7, ASYNC),
3246 MockRead(ASYNC, 0, 8),
3247 };
3248
3249 DeterministicSocketData spdy_data(
3250 spdy_reads, arraysize(spdy_reads),
3251 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073252 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223253
3254 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023255 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073256 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223257 SSLSocketDataProvider ssl2(ASYNC, OK);
3258 ssl2.was_npn_negotiated = false;
3259 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073260 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223261
3262 TestCompletionCallback callback;
3263
[email protected]262eec82013-03-19 21:01:363264 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503265 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223266 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3267 EXPECT_EQ(ERR_IO_PENDING, rv);
3268 // The first connect and request, each of their responses, and the body.
3269 spdy_data.RunFor(5);
3270
3271 rv = callback.WaitForResult();
3272 EXPECT_EQ(OK, rv);
3273
3274 LoadTimingInfo load_timing_info;
3275 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3276 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3277
3278 const HttpResponseInfo* response = trans->GetResponseInfo();
3279 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503280 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223281 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3282
3283 std::string response_data;
3284 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503285 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223286 trans.reset();
3287
[email protected]262eec82013-03-19 21:01:363288 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503289 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223290 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3291 EXPECT_EQ(ERR_IO_PENDING, rv);
3292
3293 // The second request, response, and body. There should not be a second
3294 // connect.
3295 spdy_data.RunFor(3);
3296 rv = callback.WaitForResult();
3297 EXPECT_EQ(OK, rv);
3298
3299 LoadTimingInfo load_timing_info2;
3300 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3301 TestLoadTimingReused(load_timing_info2);
3302
3303 // The requests should have the same ID.
3304 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3305
[email protected]90499482013-06-01 00:39:503306 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223307}
3308
3309// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3310// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023311TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223312 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3313 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073314 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223315 "https://proxy:70"));
3316 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073317 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223318 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073319 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223320
3321 HttpRequestInfo request1;
3322 request1.method = "GET";
3323 request1.url = GURL("http://www.google.com/");
3324 request1.load_flags = 0;
3325
3326 HttpRequestInfo request2;
3327 request2.method = "GET";
3328 request2.url = GURL("http://news.google.com/");
3329 request2.load_flags = 0;
3330
3331 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023332 scoped_ptr<SpdyHeaderBlock> headers(
3333 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233334 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023335 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3336 scoped_ptr<SpdyFrame> get_resp1(
3337 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3338 scoped_ptr<SpdyFrame> body1(
3339 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223340
3341 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023342 scoped_ptr<SpdyHeaderBlock> headers2(
3343 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233344 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023345 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3346 scoped_ptr<SpdyFrame> get_resp2(
3347 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3348 scoped_ptr<SpdyFrame> body2(
3349 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223350
3351 MockWrite spdy_writes[] = {
3352 CreateMockWrite(*get1, 0),
3353 CreateMockWrite(*get2, 3),
3354 };
3355
3356 MockRead spdy_reads[] = {
3357 CreateMockRead(*get_resp1, 1, ASYNC),
3358 CreateMockRead(*body1, 2, ASYNC),
3359 CreateMockRead(*get_resp2, 4, ASYNC),
3360 CreateMockRead(*body2, 5, ASYNC),
3361 MockRead(ASYNC, 0, 6),
3362 };
3363
3364 DeterministicSocketData spdy_data(
3365 spdy_reads, arraysize(spdy_reads),
3366 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073367 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223368
3369 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023370 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073371 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223372
3373 TestCompletionCallback callback;
3374
[email protected]262eec82013-03-19 21:01:363375 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223377 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3378 EXPECT_EQ(ERR_IO_PENDING, rv);
3379 spdy_data.RunFor(2);
3380
3381 rv = callback.WaitForResult();
3382 EXPECT_EQ(OK, rv);
3383
3384 LoadTimingInfo load_timing_info;
3385 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3386 TestLoadTimingNotReused(load_timing_info,
3387 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3388
3389 const HttpResponseInfo* response = trans->GetResponseInfo();
3390 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503391 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223392 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3393
3394 std::string response_data;
3395 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503396 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223397 spdy_data.RunFor(1);
3398 EXPECT_EQ(1, callback.WaitForResult());
3399 // Delete the first request, so the second one can reuse the socket.
3400 trans.reset();
3401
[email protected]262eec82013-03-19 21:01:363402 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503403 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223404 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3405 EXPECT_EQ(ERR_IO_PENDING, rv);
3406
3407 spdy_data.RunFor(2);
3408 rv = callback.WaitForResult();
3409 EXPECT_EQ(OK, rv);
3410
3411 LoadTimingInfo load_timing_info2;
3412 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3413 TestLoadTimingReused(load_timing_info2);
3414
3415 // The requests should have the same ID.
3416 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3417
[email protected]90499482013-06-01 00:39:503418 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223419 spdy_data.RunFor(1);
3420 EXPECT_EQ(2, callback.WaitForResult());
3421}
3422
[email protected]2df19bb2010-08-25 20:13:463423// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023424TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463425 HttpRequestInfo request;
3426 request.method = "GET";
3427 request.url = GURL("http://www.google.com/");
3428 // when the no authentication data flag is set.
3429 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3430
[email protected]79cb5c12011-09-12 13:12:043431 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073432 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043433 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293434 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073435 session_deps_.net_log = log.bound().net_log();
3436 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273437
[email protected]2df19bb2010-08-25 20:13:463438 // Since we have proxy, should use full url
3439 MockWrite data_writes1[] = {
3440 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3441 "Host: www.google.com\r\n"
3442 "Proxy-Connection: keep-alive\r\n\r\n"),
3443
3444 // After calling trans->RestartWithAuth(), this is the request we should
3445 // be issuing -- the final header line contains the credentials.
3446 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3447 "Host: www.google.com\r\n"
3448 "Proxy-Connection: keep-alive\r\n"
3449 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3450 };
3451
3452 // The proxy responds to the GET with a 407, using a persistent
3453 // connection.
3454 MockRead data_reads1[] = {
3455 // No credentials.
3456 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3457 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3458 MockRead("Proxy-Connection: keep-alive\r\n"),
3459 MockRead("Content-Length: 0\r\n\r\n"),
3460
3461 MockRead("HTTP/1.1 200 OK\r\n"),
3462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3463 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063464 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463465 };
3466
3467 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3468 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073469 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063470 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463472
[email protected]49639fa2011-12-20 23:22:413473 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463474
[email protected]262eec82013-03-19 21:01:363475 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503476 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503477
[email protected]49639fa2011-12-20 23:22:413478 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463479 EXPECT_EQ(ERR_IO_PENDING, rv);
3480
3481 rv = callback1.WaitForResult();
3482 EXPECT_EQ(OK, rv);
3483
[email protected]58e32bb2013-01-21 18:23:253484 LoadTimingInfo load_timing_info;
3485 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3486 TestLoadTimingNotReused(load_timing_info,
3487 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3488
[email protected]2df19bb2010-08-25 20:13:463489 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503490 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503491 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463492 EXPECT_EQ(407, response->headers->response_code());
3493 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043494 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463495
[email protected]49639fa2011-12-20 23:22:413496 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463497
[email protected]49639fa2011-12-20 23:22:413498 rv = trans->RestartWithAuth(
3499 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463500 EXPECT_EQ(ERR_IO_PENDING, rv);
3501
3502 rv = callback2.WaitForResult();
3503 EXPECT_EQ(OK, rv);
3504
[email protected]58e32bb2013-01-21 18:23:253505 load_timing_info = LoadTimingInfo();
3506 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3507 // Retrying with HTTP AUTH is considered to be reusing a socket.
3508 TestLoadTimingReused(load_timing_info);
3509
[email protected]2df19bb2010-08-25 20:13:463510 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503511 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463512
3513 EXPECT_TRUE(response->headers->IsKeepAlive());
3514 EXPECT_EQ(200, response->headers->response_code());
3515 EXPECT_EQ(100, response->headers->GetContentLength());
3516 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3517
3518 // The password prompt info should not be set.
3519 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3520}
3521
[email protected]23e482282013-06-14 16:08:023522void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083523 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423524 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083525 request.method = "GET";
3526 request.url = GURL("https://www.google.com/");
3527 request.load_flags = 0;
3528
[email protected]cb9bf6ca2011-01-28 13:15:273529 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073530 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:273531
[email protected]bb88e1d32013-05-03 23:11:073532 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273533
[email protected]c744cf22009-02-27 07:28:083534 // Since we have proxy, should try to establish tunnel.
3535 MockWrite data_writes[] = {
3536 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453537 "Host: www.google.com\r\n"
3538 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083539 };
3540
3541 MockRead data_reads[] = {
3542 status,
3543 MockRead("Content-Length: 10\r\n\r\n"),
3544 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063545 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083546 };
3547
[email protected]31a2bfe2010-02-09 08:03:393548 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3549 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073550 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083551
[email protected]49639fa2011-12-20 23:22:413552 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083553
[email protected]262eec82013-03-19 21:01:363554 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503556
[email protected]49639fa2011-12-20 23:22:413557 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423558 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083559
3560 rv = callback.WaitForResult();
3561 EXPECT_EQ(expected_status, rv);
3562}
3563
[email protected]23e482282013-06-14 16:08:023564void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233565 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083566 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423567 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083568}
3569
[email protected]23e482282013-06-14 16:08:023570TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083571 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3572}
3573
[email protected]23e482282013-06-14 16:08:023574TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083575 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3576}
3577
[email protected]23e482282013-06-14 16:08:023578TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083579 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3580}
3581
[email protected]23e482282013-06-14 16:08:023582TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083583 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3584}
3585
[email protected]23e482282013-06-14 16:08:023586TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083587 ConnectStatusHelper(
3588 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3589}
3590
[email protected]23e482282013-06-14 16:08:023591TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083592 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3593}
3594
[email protected]23e482282013-06-14 16:08:023595TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083596 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3597}
3598
[email protected]23e482282013-06-14 16:08:023599TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083600 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3601}
3602
[email protected]23e482282013-06-14 16:08:023603TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083604 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3605}
3606
[email protected]23e482282013-06-14 16:08:023607TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083608 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3609}
3610
[email protected]23e482282013-06-14 16:08:023611TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083612 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3613}
3614
[email protected]23e482282013-06-14 16:08:023615TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083616 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3617}
3618
[email protected]23e482282013-06-14 16:08:023619TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083620 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3621}
3622
[email protected]23e482282013-06-14 16:08:023623TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083624 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3625}
3626
[email protected]23e482282013-06-14 16:08:023627TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083628 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3629}
3630
[email protected]23e482282013-06-14 16:08:023631TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083632 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3633}
3634
[email protected]23e482282013-06-14 16:08:023635TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083636 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3637}
3638
[email protected]23e482282013-06-14 16:08:023639TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083640 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3641}
3642
[email protected]23e482282013-06-14 16:08:023643TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083644 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3645}
3646
[email protected]23e482282013-06-14 16:08:023647TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083648 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3649}
3650
[email protected]23e482282013-06-14 16:08:023651TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083652 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3653}
3654
[email protected]23e482282013-06-14 16:08:023655TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083656 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3657}
3658
[email protected]23e482282013-06-14 16:08:023659TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083660 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3661}
3662
[email protected]23e482282013-06-14 16:08:023663TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083664 ConnectStatusHelperWithExpectedStatus(
3665 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543666 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083667}
3668
[email protected]23e482282013-06-14 16:08:023669TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083670 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3671}
3672
[email protected]23e482282013-06-14 16:08:023673TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083674 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3675}
3676
[email protected]23e482282013-06-14 16:08:023677TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083678 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3679}
3680
[email protected]23e482282013-06-14 16:08:023681TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083682 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3683}
3684
[email protected]23e482282013-06-14 16:08:023685TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083686 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3687}
3688
[email protected]23e482282013-06-14 16:08:023689TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083690 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3691}
3692
[email protected]23e482282013-06-14 16:08:023693TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083694 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3695}
3696
[email protected]23e482282013-06-14 16:08:023697TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083698 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3699}
3700
[email protected]23e482282013-06-14 16:08:023701TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083702 ConnectStatusHelper(
3703 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3704}
3705
[email protected]23e482282013-06-14 16:08:023706TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083707 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3708}
3709
[email protected]23e482282013-06-14 16:08:023710TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083711 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3712}
3713
[email protected]23e482282013-06-14 16:08:023714TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083715 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3716}
3717
[email protected]23e482282013-06-14 16:08:023718TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083719 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3720}
3721
[email protected]23e482282013-06-14 16:08:023722TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083723 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3724}
3725
[email protected]23e482282013-06-14 16:08:023726TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083727 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3728}
3729
[email protected]23e482282013-06-14 16:08:023730TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083731 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3732}
3733
[email protected]038e9a32008-10-08 22:40:163734// Test the flow when both the proxy server AND origin server require
3735// authentication. Again, this uses basic auth for both since that is
3736// the simplest to mock.
[email protected]23e482282013-06-14 16:08:023737TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:273738 HttpRequestInfo request;
3739 request.method = "GET";
3740 request.url = GURL("http://www.google.com/");
3741 request.load_flags = 0;
3742
[email protected]bb88e1d32013-05-03 23:11:073743 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:013744
[email protected]038e9a32008-10-08 22:40:163745 // Configure against proxy server "myproxy:70".
[email protected]262eec82013-03-19 21:01:363746 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:073747 CreateSession(&session_deps_)));
[email protected]038e9a32008-10-08 22:40:163748
[email protected]f9ee6b52008-11-08 06:46:233749 MockWrite data_writes1[] = {
3750 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3751 "Host: www.google.com\r\n"
3752 "Proxy-Connection: keep-alive\r\n\r\n"),
3753 };
3754
[email protected]038e9a32008-10-08 22:40:163755 MockRead data_reads1[] = {
3756 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3757 // Give a couple authenticate options (only the middle one is actually
3758 // supported).
[email protected]22927ad2009-09-21 19:56:193759 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:163760 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3761 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3762 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3763 // Large content-length -- won't matter, as connection will be reset.
3764 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063765 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:163766 };
3767
3768 // After calling trans->RestartWithAuth() the first time, this is the
3769 // request we should be issuing -- the final header line contains the
3770 // proxy's credentials.
3771 MockWrite data_writes2[] = {
3772 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3773 "Host: www.google.com\r\n"
3774 "Proxy-Connection: keep-alive\r\n"
3775 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3776 };
3777
3778 // Now the proxy server lets the request pass through to origin server.
3779 // The origin server responds with a 401.
3780 MockRead data_reads2[] = {
3781 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3782 // Note: We are using the same realm-name as the proxy server. This is
3783 // completely valid, as realms are unique across hosts.
3784 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3785 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3786 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063787 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:163788 };
3789
3790 // After calling trans->RestartWithAuth() the second time, we should send
3791 // the credentials for both the proxy and origin server.
3792 MockWrite data_writes3[] = {
3793 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3794 "Host: www.google.com\r\n"
3795 "Proxy-Connection: keep-alive\r\n"
3796 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3797 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3798 };
3799
3800 // Lastly we get the desired content.
3801 MockRead data_reads3[] = {
3802 MockRead("HTTP/1.0 200 OK\r\n"),
3803 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3804 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063805 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:163806 };
3807
[email protected]31a2bfe2010-02-09 08:03:393808 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3809 data_writes1, arraysize(data_writes1));
3810 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3811 data_writes2, arraysize(data_writes2));
3812 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3813 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:073814 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3816 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:163817
[email protected]49639fa2011-12-20 23:22:413818 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:163819
[email protected]49639fa2011-12-20 23:22:413820 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423821 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163822
3823 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423824 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163825
[email protected]1c773ea12009-04-28 19:58:423826 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503827 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043828 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163829
[email protected]49639fa2011-12-20 23:22:413830 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:163831
[email protected]49639fa2011-12-20 23:22:413832 rv = trans->RestartWithAuth(
3833 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423834 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163835
3836 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423837 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163838
3839 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503840 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043841 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163842
[email protected]49639fa2011-12-20 23:22:413843 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:163844
[email protected]49639fa2011-12-20 23:22:413845 rv = trans->RestartWithAuth(
3846 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423847 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163848
3849 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423850 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163851
3852 response = trans->GetResponseInfo();
3853 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3854 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:163855}
[email protected]4ddaf2502008-10-23 18:26:193856
[email protected]ea9dc9a2009-09-05 00:43:323857// For the NTLM implementation using SSPI, we skip the NTLM tests since we
3858// can't hook into its internals to cause it to generate predictable NTLM
3859// authorization headers.
3860#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:293861// The NTLM authentication unit tests were generated by capturing the HTTP
3862// requests and responses using Fiddler 2 and inspecting the generated random
3863// bytes in the debugger.
3864
3865// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:023866TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:423867 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:243868 request.method = "GET";
3869 request.url = GURL("http://172.22.68.17/kids/login.aspx");
3870 request.load_flags = 0;
3871
[email protected]cb9bf6ca2011-01-28 13:15:273872 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
3873 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:073874 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273875
[email protected]3f918782009-02-28 01:29:243876 MockWrite data_writes1[] = {
3877 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3878 "Host: 172.22.68.17\r\n"
3879 "Connection: keep-alive\r\n\r\n"),
3880 };
3881
3882 MockRead data_reads1[] = {
3883 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043884 // Negotiate and NTLM are often requested together. However, we only want
3885 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3886 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:243887 MockRead("WWW-Authenticate: NTLM\r\n"),
3888 MockRead("Connection: close\r\n"),
3889 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363890 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243891 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:063892 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:243893 };
3894
3895 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:223896 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:243897 // request we should be issuing -- the final header line contains a Type
3898 // 1 message.
3899 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3900 "Host: 172.22.68.17\r\n"
3901 "Connection: keep-alive\r\n"
3902 "Authorization: NTLM "
3903 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3904
3905 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3906 // (the credentials for the origin server). The second request continues
3907 // on the same connection.
3908 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3909 "Host: 172.22.68.17\r\n"
3910 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:293911 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3912 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3913 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
3914 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
3915 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243916 };
3917
3918 MockRead data_reads2[] = {
3919 // The origin server responds with a Type 2 message.
3920 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3921 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:293922 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:243923 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3924 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3925 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3926 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3927 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3928 "BtAAAAAAA=\r\n"),
3929 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363930 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243931 MockRead("You are not authorized to view this page\r\n"),
3932
3933 // Lastly we get the desired content.
3934 MockRead("HTTP/1.1 200 OK\r\n"),
3935 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3936 MockRead("Content-Length: 13\r\n\r\n"),
3937 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:063938 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:243939 };
3940
[email protected]31a2bfe2010-02-09 08:03:393941 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3942 data_writes1, arraysize(data_writes1));
3943 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3944 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3946 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:243947
[email protected]49639fa2011-12-20 23:22:413948 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:243949
[email protected]262eec82013-03-19 21:01:363950 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503951 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503952
[email protected]49639fa2011-12-20 23:22:413953 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423954 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243955
3956 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423957 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243958
[email protected]0757e7702009-03-27 04:00:223959 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3960
[email protected]1c773ea12009-04-28 19:58:423961 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043962 ASSERT_FALSE(response == NULL);
3963 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:243964
[email protected]49639fa2011-12-20 23:22:413965 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:253966
[email protected]f3cf9802011-10-28 18:44:583967 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:413968 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:253969 EXPECT_EQ(ERR_IO_PENDING, rv);
3970
3971 rv = callback2.WaitForResult();
3972 EXPECT_EQ(OK, rv);
3973
3974 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3975
3976 response = trans->GetResponseInfo();
3977 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:253978 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3979
[email protected]49639fa2011-12-20 23:22:413980 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:243981
[email protected]49639fa2011-12-20 23:22:413982 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423983 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243984
[email protected]0757e7702009-03-27 04:00:223985 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423986 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243987
3988 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503989 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:243990 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3991 EXPECT_EQ(13, response->headers->GetContentLength());
3992}
3993
[email protected]385a4672009-03-11 22:21:293994// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:023995TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:423996 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:293997 request.method = "GET";
3998 request.url = GURL("http://172.22.68.17/kids/login.aspx");
3999 request.load_flags = 0;
4000
[email protected]cb9bf6ca2011-01-28 13:15:274001 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4002 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074003 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274004
[email protected]385a4672009-03-11 22:21:294005 MockWrite data_writes1[] = {
4006 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4007 "Host: 172.22.68.17\r\n"
4008 "Connection: keep-alive\r\n\r\n"),
4009 };
4010
4011 MockRead data_reads1[] = {
4012 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044013 // Negotiate and NTLM are often requested together. However, we only want
4014 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4015 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294016 MockRead("WWW-Authenticate: NTLM\r\n"),
4017 MockRead("Connection: close\r\n"),
4018 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364019 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294020 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064021 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294022 };
4023
4024 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224025 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294026 // request we should be issuing -- the final header line contains a Type
4027 // 1 message.
4028 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4029 "Host: 172.22.68.17\r\n"
4030 "Connection: keep-alive\r\n"
4031 "Authorization: NTLM "
4032 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4033
4034 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4035 // (the credentials for the origin server). The second request continues
4036 // on the same connection.
4037 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4038 "Host: 172.22.68.17\r\n"
4039 "Connection: keep-alive\r\n"
4040 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4041 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4042 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4043 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4044 "4Ww7b7E=\r\n\r\n"),
4045 };
4046
4047 MockRead data_reads2[] = {
4048 // The origin server responds with a Type 2 message.
4049 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4050 MockRead("WWW-Authenticate: NTLM "
4051 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4052 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4053 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4054 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4055 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4056 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4057 "BtAAAAAAA=\r\n"),
4058 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364059 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294060 MockRead("You are not authorized to view this page\r\n"),
4061
4062 // Wrong password.
4063 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294064 MockRead("WWW-Authenticate: NTLM\r\n"),
4065 MockRead("Connection: close\r\n"),
4066 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364067 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294068 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064069 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294070 };
4071
4072 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224073 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294074 // request we should be issuing -- the final header line contains a Type
4075 // 1 message.
4076 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4077 "Host: 172.22.68.17\r\n"
4078 "Connection: keep-alive\r\n"
4079 "Authorization: NTLM "
4080 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4081
4082 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4083 // (the credentials for the origin server). The second request continues
4084 // on the same connection.
4085 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4086 "Host: 172.22.68.17\r\n"
4087 "Connection: keep-alive\r\n"
4088 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4089 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4090 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4091 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4092 "+4MUm7c=\r\n\r\n"),
4093 };
4094
4095 MockRead data_reads3[] = {
4096 // The origin server responds with a Type 2 message.
4097 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4098 MockRead("WWW-Authenticate: NTLM "
4099 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4100 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4101 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4102 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4103 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4104 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4105 "BtAAAAAAA=\r\n"),
4106 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364107 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294108 MockRead("You are not authorized to view this page\r\n"),
4109
4110 // Lastly we get the desired content.
4111 MockRead("HTTP/1.1 200 OK\r\n"),
4112 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4113 MockRead("Content-Length: 13\r\n\r\n"),
4114 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064115 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294116 };
4117
[email protected]31a2bfe2010-02-09 08:03:394118 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4119 data_writes1, arraysize(data_writes1));
4120 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4121 data_writes2, arraysize(data_writes2));
4122 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4123 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074124 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4125 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4126 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294127
[email protected]49639fa2011-12-20 23:22:414128 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294129
[email protected]262eec82013-03-19 21:01:364130 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504131 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504132
[email protected]49639fa2011-12-20 23:22:414133 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424134 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294135
4136 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424137 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294138
[email protected]0757e7702009-03-27 04:00:224139 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294140
[email protected]1c773ea12009-04-28 19:58:424141 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504142 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044143 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294144
[email protected]49639fa2011-12-20 23:22:414145 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294146
[email protected]0757e7702009-03-27 04:00:224147 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584148 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414149 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424150 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294151
[email protected]10af5fe72011-01-31 16:17:254152 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424153 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294154
[email protected]0757e7702009-03-27 04:00:224155 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414156 TestCompletionCallback callback3;
4157 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424158 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254159 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424160 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224161 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4162
4163 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044164 ASSERT_FALSE(response == NULL);
4165 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224166
[email protected]49639fa2011-12-20 23:22:414167 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224168
4169 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584170 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414171 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254172 EXPECT_EQ(ERR_IO_PENDING, rv);
4173
4174 rv = callback4.WaitForResult();
4175 EXPECT_EQ(OK, rv);
4176
4177 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4178
[email protected]49639fa2011-12-20 23:22:414179 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254180
4181 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414182 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424183 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224184
4185 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424186 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224187
[email protected]385a4672009-03-11 22:21:294188 response = trans->GetResponseInfo();
4189 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4190 EXPECT_EQ(13, response->headers->GetContentLength());
4191}
[email protected]ea9dc9a2009-09-05 00:43:324192#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294193
[email protected]4ddaf2502008-10-23 18:26:194194// Test reading a server response which has only headers, and no body.
4195// After some maximum number of bytes is consumed, the transaction should
4196// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024197TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424198 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194199 request.method = "GET";
4200 request.url = GURL("http://www.google.com/");
4201 request.load_flags = 0;
4202
[email protected]cb9bf6ca2011-01-28 13:15:274203 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364204 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074205 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274206
[email protected]b75b7b2f2009-10-06 00:54:534207 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434208 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534209 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194210
4211 MockRead data_reads[] = {
4212 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064213 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194214 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064215 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194216 };
[email protected]31a2bfe2010-02-09 08:03:394217 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074218 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194219
[email protected]49639fa2011-12-20 23:22:414220 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194221
[email protected]49639fa2011-12-20 23:22:414222 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424223 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194224
4225 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424226 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194227
[email protected]1c773ea12009-04-28 19:58:424228 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194229 EXPECT_TRUE(response == NULL);
4230}
[email protected]f4e426b2008-11-05 00:24:494231
4232// Make sure that we don't try to reuse a TCPClientSocket when failing to
4233// establish tunnel.
4234// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024235TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234236 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274237 HttpRequestInfo request;
4238 request.method = "GET";
4239 request.url = GURL("https://www.google.com/");
4240 request.load_flags = 0;
4241
[email protected]f4e426b2008-11-05 00:24:494242 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074243 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014244
[email protected]bb88e1d32013-05-03 23:11:074245 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494246
[email protected]262eec82013-03-19 21:01:364247 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504248 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494249
[email protected]f4e426b2008-11-05 00:24:494250 // Since we have proxy, should try to establish tunnel.
4251 MockWrite data_writes1[] = {
4252 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454253 "Host: www.google.com\r\n"
4254 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494255 };
4256
[email protected]77848d12008-11-14 00:00:224257 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494258 // connection. Usually a proxy would return 501 (not implemented),
4259 // or 200 (tunnel established).
4260 MockRead data_reads1[] = {
4261 MockRead("HTTP/1.1 404 Not Found\r\n"),
4262 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064263 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494264 };
4265
[email protected]31a2bfe2010-02-09 08:03:394266 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4267 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074268 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494269
[email protected]49639fa2011-12-20 23:22:414270 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494271
[email protected]49639fa2011-12-20 23:22:414272 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424273 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494274
4275 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424276 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494277
[email protected]1c773ea12009-04-28 19:58:424278 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084279 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494280
[email protected]b4404c02009-04-10 16:38:524281 // Empty the current queue. This is necessary because idle sockets are
4282 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344283 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524284
[email protected]f4e426b2008-11-05 00:24:494285 // We now check to make sure the TCPClientSocket was not added back to
4286 // the pool.
[email protected]90499482013-06-01 00:39:504287 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494288 trans.reset();
[email protected]2da659e2013-05-23 20:51:344289 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494290 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504291 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494292}
[email protected]372d34a2008-11-05 21:30:514293
[email protected]1b157c02009-04-21 01:55:404294// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024295TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424296 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404297 request.method = "GET";
4298 request.url = GURL("http://www.google.com/");
4299 request.load_flags = 0;
4300
[email protected]bb88e1d32013-05-03 23:11:074301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274302
[email protected]262eec82013-03-19 21:01:364303 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274305
[email protected]1b157c02009-04-21 01:55:404306 MockRead data_reads[] = {
4307 // A part of the response body is received with the response headers.
4308 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4309 // The rest of the response body is received in two parts.
4310 MockRead("lo"),
4311 MockRead(" world"),
4312 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064313 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404314 };
4315
[email protected]31a2bfe2010-02-09 08:03:394316 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074317 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404318
[email protected]49639fa2011-12-20 23:22:414319 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404320
[email protected]49639fa2011-12-20 23:22:414321 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424322 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404323
4324 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424325 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404326
[email protected]1c773ea12009-04-28 19:58:424327 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504328 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404329
[email protected]90499482013-06-01 00:39:504330 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404331 std::string status_line = response->headers->GetStatusLine();
4332 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4333
[email protected]90499482013-06-01 00:39:504334 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404335
4336 std::string response_data;
4337 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424338 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404339 EXPECT_EQ("hello world", response_data);
4340
4341 // Empty the current queue. This is necessary because idle sockets are
4342 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344343 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404344
4345 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504346 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404347}
4348
[email protected]76a505b2010-08-25 06:23:004349// Make sure that we recycle a SSL socket after reading all of the response
4350// body.
[email protected]23e482282013-06-14 16:08:024351TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004352 HttpRequestInfo request;
4353 request.method = "GET";
4354 request.url = GURL("https://www.google.com/");
4355 request.load_flags = 0;
4356
4357 MockWrite data_writes[] = {
4358 MockWrite("GET / HTTP/1.1\r\n"
4359 "Host: www.google.com\r\n"
4360 "Connection: keep-alive\r\n\r\n"),
4361 };
4362
4363 MockRead data_reads[] = {
4364 MockRead("HTTP/1.1 200 OK\r\n"),
4365 MockRead("Content-Length: 11\r\n\r\n"),
4366 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064367 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004368 };
4369
[email protected]8ddf8322012-02-23 18:08:064370 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004372
4373 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4374 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074375 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004376
[email protected]49639fa2011-12-20 23:22:414377 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004378
[email protected]bb88e1d32013-05-03 23:11:074379 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364380 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004382
[email protected]49639fa2011-12-20 23:22:414383 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004384
4385 EXPECT_EQ(ERR_IO_PENDING, rv);
4386 EXPECT_EQ(OK, callback.WaitForResult());
4387
4388 const HttpResponseInfo* response = trans->GetResponseInfo();
4389 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504390 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004391 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4392
[email protected]90499482013-06-01 00:39:504393 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004394
4395 std::string response_data;
4396 rv = ReadTransaction(trans.get(), &response_data);
4397 EXPECT_EQ(OK, rv);
4398 EXPECT_EQ("hello world", response_data);
4399
4400 // Empty the current queue. This is necessary because idle sockets are
4401 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344402 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004403
4404 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504405 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004406}
4407
4408// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4409// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024410TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004411 HttpRequestInfo request;
4412 request.method = "GET";
4413 request.url = GURL("https://www.google.com/");
4414 request.load_flags = 0;
4415
4416 MockWrite data_writes[] = {
4417 MockWrite("GET / HTTP/1.1\r\n"
4418 "Host: www.google.com\r\n"
4419 "Connection: keep-alive\r\n\r\n"),
4420 MockWrite("GET / HTTP/1.1\r\n"
4421 "Host: www.google.com\r\n"
4422 "Connection: keep-alive\r\n\r\n"),
4423 };
4424
4425 MockRead data_reads[] = {
4426 MockRead("HTTP/1.1 200 OK\r\n"),
4427 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064428 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004429 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064430 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004431 };
4432
[email protected]8ddf8322012-02-23 18:08:064433 SSLSocketDataProvider ssl(ASYNC, OK);
4434 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074435 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004437
4438 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4439 data_writes, arraysize(data_writes));
4440 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4441 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074442 session_deps_.socket_factory->AddSocketDataProvider(&data);
4443 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004444
[email protected]49639fa2011-12-20 23:22:414445 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004446
[email protected]bb88e1d32013-05-03 23:11:074447 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364448 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504449 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004450
[email protected]49639fa2011-12-20 23:22:414451 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004452
4453 EXPECT_EQ(ERR_IO_PENDING, rv);
4454 EXPECT_EQ(OK, callback.WaitForResult());
4455
4456 const HttpResponseInfo* response = trans->GetResponseInfo();
4457 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504458 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004459 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4460
[email protected]90499482013-06-01 00:39:504461 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004462
4463 std::string response_data;
4464 rv = ReadTransaction(trans.get(), &response_data);
4465 EXPECT_EQ(OK, rv);
4466 EXPECT_EQ("hello world", response_data);
4467
4468 // Empty the current queue. This is necessary because idle sockets are
4469 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344470 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004471
4472 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504473 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004474
4475 // Now start the second transaction, which should reuse the previous socket.
4476
[email protected]90499482013-06-01 00:39:504477 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004478
[email protected]49639fa2011-12-20 23:22:414479 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004480
4481 EXPECT_EQ(ERR_IO_PENDING, rv);
4482 EXPECT_EQ(OK, callback.WaitForResult());
4483
4484 response = trans->GetResponseInfo();
4485 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504486 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004487 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4488
[email protected]90499482013-06-01 00:39:504489 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004490
4491 rv = ReadTransaction(trans.get(), &response_data);
4492 EXPECT_EQ(OK, rv);
4493 EXPECT_EQ("hello world", response_data);
4494
4495 // Empty the current queue. This is necessary because idle sockets are
4496 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344497 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004498
4499 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504500 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004501}
4502
[email protected]b4404c02009-04-10 16:38:524503// Make sure that we recycle a socket after a zero-length response.
4504// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024505TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424506 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524507 request.method = "GET";
4508 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4509 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4510 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4511 "rt=prt.2642,ol.2649,xjs.2951");
4512 request.load_flags = 0;
4513
[email protected]bb88e1d32013-05-03 23:11:074514 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274515
[email protected]262eec82013-03-19 21:01:364516 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274518
[email protected]b4404c02009-04-10 16:38:524519 MockRead data_reads[] = {
4520 MockRead("HTTP/1.1 204 No Content\r\n"
4521 "Content-Length: 0\r\n"
4522 "Content-Type: text/html\r\n\r\n"),
4523 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064524 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524525 };
4526
[email protected]31a2bfe2010-02-09 08:03:394527 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074528 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524529
[email protected]49639fa2011-12-20 23:22:414530 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524531
[email protected]49639fa2011-12-20 23:22:414532 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424533 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524534
4535 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424536 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524537
[email protected]1c773ea12009-04-28 19:58:424538 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504539 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524540
[email protected]90499482013-06-01 00:39:504541 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524542 std::string status_line = response->headers->GetStatusLine();
4543 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4544
[email protected]90499482013-06-01 00:39:504545 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524546
4547 std::string response_data;
4548 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424549 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524550 EXPECT_EQ("", response_data);
4551
4552 // Empty the current queue. This is necessary because idle sockets are
4553 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344554 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524555
4556 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504557 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524558}
4559
[email protected]23e482282013-06-14 16:08:024560TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064561 ScopedVector<UploadElementReader> element_readers;
4562 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204563 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274564
[email protected]1c773ea12009-04-28 19:58:424565 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514566 // Transaction 1: a GET request that succeeds. The socket is recycled
4567 // after use.
4568 request[0].method = "GET";
4569 request[0].url = GURL("http://www.google.com/");
4570 request[0].load_flags = 0;
4571 // Transaction 2: a POST request. Reuses the socket kept alive from
4572 // transaction 1. The first attempts fails when writing the POST data.
4573 // This causes the transaction to retry with a new socket. The second
4574 // attempt succeeds.
4575 request[1].method = "POST";
4576 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274577 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514578 request[1].load_flags = 0;
4579
[email protected]bb88e1d32013-05-03 23:11:074580 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514581
4582 // The first socket is used for transaction 1 and the first attempt of
4583 // transaction 2.
4584
4585 // The response of transaction 1.
4586 MockRead data_reads1[] = {
4587 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4588 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064589 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514590 };
4591 // The mock write results of transaction 1 and the first attempt of
4592 // transaction 2.
4593 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064594 MockWrite(SYNCHRONOUS, 64), // GET
4595 MockWrite(SYNCHRONOUS, 93), // POST
4596 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514597 };
[email protected]31a2bfe2010-02-09 08:03:394598 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4599 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514600
4601 // The second socket is used for the second attempt of transaction 2.
4602
4603 // The response of transaction 2.
4604 MockRead data_reads2[] = {
4605 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4606 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064607 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514608 };
4609 // The mock write results of the second attempt of transaction 2.
4610 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064611 MockWrite(SYNCHRONOUS, 93), // POST
4612 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514613 };
[email protected]31a2bfe2010-02-09 08:03:394614 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4615 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514616
[email protected]bb88e1d32013-05-03 23:11:074617 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4618 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514619
4620 const char* kExpectedResponseData[] = {
4621 "hello world", "welcome"
4622 };
4623
4624 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424625 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504626 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514627
[email protected]49639fa2011-12-20 23:22:414628 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514629
[email protected]49639fa2011-12-20 23:22:414630 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424631 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514632
4633 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424634 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514635
[email protected]1c773ea12009-04-28 19:58:424636 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504637 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514638
[email protected]90499482013-06-01 00:39:504639 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514640 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4641
4642 std::string response_data;
4643 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424644 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514645 EXPECT_EQ(kExpectedResponseData[i], response_data);
4646 }
4647}
[email protected]f9ee6b52008-11-08 06:46:234648
4649// Test the request-challenge-retry sequence for basic auth when there is
4650// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164651// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024652TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424653 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234654 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294655 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414656 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294657
[email protected]cb9bf6ca2011-01-28 13:15:274658 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364659 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074660 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274661
[email protected]a97cca42009-08-14 01:00:294662 // The password contains an escaped character -- for this test to pass it
4663 // will need to be unescaped by HttpNetworkTransaction.
4664 EXPECT_EQ("b%40r", request.url.password());
4665
[email protected]f9ee6b52008-11-08 06:46:234666 MockWrite data_writes1[] = {
4667 MockWrite("GET / HTTP/1.1\r\n"
4668 "Host: www.google.com\r\n"
4669 "Connection: keep-alive\r\n\r\n"),
4670 };
4671
4672 MockRead data_reads1[] = {
4673 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4674 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4675 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064676 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234677 };
4678
[email protected]2262e3a2012-05-22 16:08:164679 // After the challenge above, the transaction will be restarted using the
4680 // identity from the url (foo, b@r) to answer the challenge.
4681 MockWrite data_writes2[] = {
4682 MockWrite("GET / HTTP/1.1\r\n"
4683 "Host: www.google.com\r\n"
4684 "Connection: keep-alive\r\n"
4685 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4686 };
4687
4688 MockRead data_reads2[] = {
4689 MockRead("HTTP/1.0 200 OK\r\n"),
4690 MockRead("Content-Length: 100\r\n\r\n"),
4691 MockRead(SYNCHRONOUS, OK),
4692 };
4693
[email protected]31a2bfe2010-02-09 08:03:394694 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4695 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164696 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4697 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074698 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4699 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234700
[email protected]49639fa2011-12-20 23:22:414701 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414702 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424703 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234704 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424705 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164706 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4707
4708 TestCompletionCallback callback2;
4709 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4710 EXPECT_EQ(ERR_IO_PENDING, rv);
4711 rv = callback2.WaitForResult();
4712 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224713 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4714
[email protected]2262e3a2012-05-22 16:08:164715 const HttpResponseInfo* response = trans->GetResponseInfo();
4716 ASSERT_TRUE(response != NULL);
4717
4718 // There is no challenge info, since the identity in URL worked.
4719 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4720
4721 EXPECT_EQ(100, response->headers->GetContentLength());
4722
4723 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344724 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164725}
4726
4727// Test the request-challenge-retry sequence for basic auth when there is an
4728// incorrect identity in the URL. The identity from the URL should be used only
4729// once.
[email protected]23e482282013-06-14 16:08:024730TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164731 HttpRequestInfo request;
4732 request.method = "GET";
4733 // Note: the URL has a username:password in it. The password "baz" is
4734 // wrong (should be "bar").
4735 request.url = GURL("http://foo:[email protected]/");
4736
4737 request.load_flags = LOAD_NORMAL;
4738
[email protected]2262e3a2012-05-22 16:08:164739 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364740 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074741 CreateSession(&session_deps_)));
[email protected]2262e3a2012-05-22 16:08:164742
4743 MockWrite data_writes1[] = {
4744 MockWrite("GET / HTTP/1.1\r\n"
4745 "Host: www.google.com\r\n"
4746 "Connection: keep-alive\r\n\r\n"),
4747 };
4748
4749 MockRead data_reads1[] = {
4750 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4751 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4752 MockRead("Content-Length: 10\r\n\r\n"),
4753 MockRead(SYNCHRONOUS, ERR_FAILED),
4754 };
4755
4756 // After the challenge above, the transaction will be restarted using the
4757 // identity from the url (foo, baz) to answer the challenge.
4758 MockWrite data_writes2[] = {
4759 MockWrite("GET / HTTP/1.1\r\n"
4760 "Host: www.google.com\r\n"
4761 "Connection: keep-alive\r\n"
4762 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4763 };
4764
4765 MockRead data_reads2[] = {
4766 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4767 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4768 MockRead("Content-Length: 10\r\n\r\n"),
4769 MockRead(SYNCHRONOUS, ERR_FAILED),
4770 };
4771
4772 // After the challenge above, the transaction will be restarted using the
4773 // identity supplied by the user (foo, bar) to answer the challenge.
4774 MockWrite data_writes3[] = {
4775 MockWrite("GET / HTTP/1.1\r\n"
4776 "Host: www.google.com\r\n"
4777 "Connection: keep-alive\r\n"
4778 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4779 };
4780
4781 MockRead data_reads3[] = {
4782 MockRead("HTTP/1.0 200 OK\r\n"),
4783 MockRead("Content-Length: 100\r\n\r\n"),
4784 MockRead(SYNCHRONOUS, OK),
4785 };
4786
4787 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4788 data_writes1, arraysize(data_writes1));
4789 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4790 data_writes2, arraysize(data_writes2));
4791 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4792 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074793 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4794 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4795 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:164796
4797 TestCompletionCallback callback1;
4798
4799 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4800 EXPECT_EQ(ERR_IO_PENDING, rv);
4801
4802 rv = callback1.WaitForResult();
4803 EXPECT_EQ(OK, rv);
4804
4805 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4806 TestCompletionCallback callback2;
4807 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4808 EXPECT_EQ(ERR_IO_PENDING, rv);
4809 rv = callback2.WaitForResult();
4810 EXPECT_EQ(OK, rv);
4811 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4812
4813 const HttpResponseInfo* response = trans->GetResponseInfo();
4814 ASSERT_TRUE(response != NULL);
4815 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4816
4817 TestCompletionCallback callback3;
4818 rv = trans->RestartWithAuth(
4819 AuthCredentials(kFoo, kBar), callback3.callback());
4820 EXPECT_EQ(ERR_IO_PENDING, rv);
4821 rv = callback3.WaitForResult();
4822 EXPECT_EQ(OK, rv);
4823 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4824
4825 response = trans->GetResponseInfo();
4826 ASSERT_TRUE(response != NULL);
4827
4828 // There is no challenge info, since the identity worked.
4829 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4830
4831 EXPECT_EQ(100, response->headers->GetContentLength());
4832
[email protected]ea9dc9a2009-09-05 00:43:324833 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344834 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:324835}
4836
[email protected]f9ee6b52008-11-08 06:46:234837// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:024838TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:074839 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:234840
4841 // Transaction 1: authenticate (foo, bar) on MyRealm1
4842 {
[email protected]1c773ea12009-04-28 19:58:424843 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234844 request.method = "GET";
4845 request.url = GURL("http://www.google.com/x/y/z");
4846 request.load_flags = 0;
4847
[email protected]262eec82013-03-19 21:01:364848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274850
[email protected]f9ee6b52008-11-08 06:46:234851 MockWrite data_writes1[] = {
4852 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4853 "Host: www.google.com\r\n"
4854 "Connection: keep-alive\r\n\r\n"),
4855 };
4856
4857 MockRead data_reads1[] = {
4858 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4859 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4860 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064861 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234862 };
4863
4864 // Resend with authorization (username=foo, password=bar)
4865 MockWrite data_writes2[] = {
4866 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4867 "Host: www.google.com\r\n"
4868 "Connection: keep-alive\r\n"
4869 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4870 };
4871
4872 // Sever accepts the authorization.
4873 MockRead data_reads2[] = {
4874 MockRead("HTTP/1.0 200 OK\r\n"),
4875 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064876 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234877 };
4878
[email protected]31a2bfe2010-02-09 08:03:394879 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4880 data_writes1, arraysize(data_writes1));
4881 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4882 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074883 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4884 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234885
[email protected]49639fa2011-12-20 23:22:414886 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234887
[email protected]49639fa2011-12-20 23:22:414888 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424889 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234890
4891 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424892 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234893
[email protected]1c773ea12009-04-28 19:58:424894 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504895 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044896 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:234897
[email protected]49639fa2011-12-20 23:22:414898 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234899
[email protected]49639fa2011-12-20 23:22:414900 rv = trans->RestartWithAuth(
4901 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234903
4904 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424905 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234906
4907 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504908 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234909 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4910 EXPECT_EQ(100, response->headers->GetContentLength());
4911 }
4912
4913 // ------------------------------------------------------------------------
4914
4915 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
4916 {
[email protected]1c773ea12009-04-28 19:58:424917 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234918 request.method = "GET";
4919 // Note that Transaction 1 was at /x/y/z, so this is in the same
4920 // protection space as MyRealm1.
4921 request.url = GURL("http://www.google.com/x/y/a/b");
4922 request.load_flags = 0;
4923
[email protected]262eec82013-03-19 21:01:364924 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504925 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274926
[email protected]f9ee6b52008-11-08 06:46:234927 MockWrite data_writes1[] = {
4928 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4929 "Host: www.google.com\r\n"
4930 "Connection: keep-alive\r\n"
4931 // Send preemptive authorization for MyRealm1
4932 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4933 };
4934
4935 // The server didn't like the preemptive authorization, and
4936 // challenges us for a different realm (MyRealm2).
4937 MockRead data_reads1[] = {
4938 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4939 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
4940 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064941 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234942 };
4943
4944 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
4945 MockWrite data_writes2[] = {
4946 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4947 "Host: www.google.com\r\n"
4948 "Connection: keep-alive\r\n"
4949 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4950 };
4951
4952 // Sever accepts the authorization.
4953 MockRead data_reads2[] = {
4954 MockRead("HTTP/1.0 200 OK\r\n"),
4955 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064956 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234957 };
4958
[email protected]31a2bfe2010-02-09 08:03:394959 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4960 data_writes1, arraysize(data_writes1));
4961 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4962 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074963 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4964 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234965
[email protected]49639fa2011-12-20 23:22:414966 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234967
[email protected]49639fa2011-12-20 23:22:414968 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424969 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234970
4971 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424972 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234973
[email protected]1c773ea12009-04-28 19:58:424974 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504975 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044976 ASSERT_TRUE(response->auth_challenge.get());
4977 EXPECT_FALSE(response->auth_challenge->is_proxy);
4978 EXPECT_EQ("www.google.com:80",
4979 response->auth_challenge->challenger.ToString());
4980 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
4981 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:234982
[email protected]49639fa2011-12-20 23:22:414983 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234984
[email protected]49639fa2011-12-20 23:22:414985 rv = trans->RestartWithAuth(
4986 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424987 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234988
4989 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424990 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234991
4992 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504993 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234994 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4995 EXPECT_EQ(100, response->headers->GetContentLength());
4996 }
4997
4998 // ------------------------------------------------------------------------
4999
5000 // Transaction 3: Resend a request in MyRealm's protection space --
5001 // succeed with preemptive authorization.
5002 {
[email protected]1c773ea12009-04-28 19:58:425003 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235004 request.method = "GET";
5005 request.url = GURL("http://www.google.com/x/y/z2");
5006 request.load_flags = 0;
5007
[email protected]262eec82013-03-19 21:01:365008 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505009 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275010
[email protected]f9ee6b52008-11-08 06:46:235011 MockWrite data_writes1[] = {
5012 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5013 "Host: www.google.com\r\n"
5014 "Connection: keep-alive\r\n"
5015 // The authorization for MyRealm1 gets sent preemptively
5016 // (since the url is in the same protection space)
5017 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5018 };
5019
5020 // Sever accepts the preemptive authorization
5021 MockRead data_reads1[] = {
5022 MockRead("HTTP/1.0 200 OK\r\n"),
5023 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065024 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235025 };
5026
[email protected]31a2bfe2010-02-09 08:03:395027 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5028 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075029 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235030
[email protected]49639fa2011-12-20 23:22:415031 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235032
[email protected]49639fa2011-12-20 23:22:415033 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425034 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235035
5036 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425037 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235038
[email protected]1c773ea12009-04-28 19:58:425039 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505040 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235041
5042 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5043 EXPECT_EQ(100, response->headers->GetContentLength());
5044 }
5045
5046 // ------------------------------------------------------------------------
5047
5048 // Transaction 4: request another URL in MyRealm (however the
5049 // url is not known to belong to the protection space, so no pre-auth).
5050 {
[email protected]1c773ea12009-04-28 19:58:425051 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235052 request.method = "GET";
5053 request.url = GURL("http://www.google.com/x/1");
5054 request.load_flags = 0;
5055
[email protected]262eec82013-03-19 21:01:365056 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505057 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275058
[email protected]f9ee6b52008-11-08 06:46:235059 MockWrite data_writes1[] = {
5060 MockWrite("GET /x/1 HTTP/1.1\r\n"
5061 "Host: www.google.com\r\n"
5062 "Connection: keep-alive\r\n\r\n"),
5063 };
5064
5065 MockRead data_reads1[] = {
5066 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5067 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5068 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065069 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235070 };
5071
5072 // Resend with authorization from MyRealm's cache.
5073 MockWrite data_writes2[] = {
5074 MockWrite("GET /x/1 HTTP/1.1\r\n"
5075 "Host: www.google.com\r\n"
5076 "Connection: keep-alive\r\n"
5077 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5078 };
5079
5080 // Sever accepts the authorization.
5081 MockRead data_reads2[] = {
5082 MockRead("HTTP/1.0 200 OK\r\n"),
5083 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065084 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235085 };
5086
[email protected]31a2bfe2010-02-09 08:03:395087 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5088 data_writes1, arraysize(data_writes1));
5089 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5090 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075091 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5092 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235093
[email protected]49639fa2011-12-20 23:22:415094 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235095
[email protected]49639fa2011-12-20 23:22:415096 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425097 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235098
5099 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425100 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235101
[email protected]0757e7702009-03-27 04:00:225102 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415103 TestCompletionCallback callback2;
5104 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425105 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225106 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425107 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225108 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5109
[email protected]1c773ea12009-04-28 19:58:425110 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505111 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235112 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5113 EXPECT_EQ(100, response->headers->GetContentLength());
5114 }
5115
5116 // ------------------------------------------------------------------------
5117
5118 // Transaction 5: request a URL in MyRealm, but the server rejects the
5119 // cached identity. Should invalidate and re-prompt.
5120 {
[email protected]1c773ea12009-04-28 19:58:425121 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235122 request.method = "GET";
5123 request.url = GURL("http://www.google.com/p/q/t");
5124 request.load_flags = 0;
5125
[email protected]262eec82013-03-19 21:01:365126 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505127 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275128
[email protected]f9ee6b52008-11-08 06:46:235129 MockWrite data_writes1[] = {
5130 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5131 "Host: www.google.com\r\n"
5132 "Connection: keep-alive\r\n\r\n"),
5133 };
5134
5135 MockRead data_reads1[] = {
5136 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5137 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5138 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065139 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235140 };
5141
5142 // Resend with authorization from cache for MyRealm.
5143 MockWrite data_writes2[] = {
5144 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5145 "Host: www.google.com\r\n"
5146 "Connection: keep-alive\r\n"
5147 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5148 };
5149
5150 // Sever rejects the authorization.
5151 MockRead data_reads2[] = {
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 // At this point we should prompt for new credentials for MyRealm.
5159 // Restart with username=foo3, password=foo4.
5160 MockWrite data_writes3[] = {
5161 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5162 "Host: www.google.com\r\n"
5163 "Connection: keep-alive\r\n"
5164 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5165 };
5166
5167 // Sever accepts the authorization.
5168 MockRead data_reads3[] = {
5169 MockRead("HTTP/1.0 200 OK\r\n"),
5170 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065171 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235172 };
5173
[email protected]31a2bfe2010-02-09 08:03:395174 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5175 data_writes1, arraysize(data_writes1));
5176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5177 data_writes2, arraysize(data_writes2));
5178 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5179 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075180 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5181 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5182 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235183
[email protected]49639fa2011-12-20 23:22:415184 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235185
[email protected]49639fa2011-12-20 23:22:415186 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425187 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235188
5189 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425190 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235191
[email protected]0757e7702009-03-27 04:00:225192 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415193 TestCompletionCallback callback2;
5194 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425195 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225196 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425197 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225198 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5199
[email protected]1c773ea12009-04-28 19:58:425200 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505201 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045202 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235203
[email protected]49639fa2011-12-20 23:22:415204 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235205
[email protected]49639fa2011-12-20 23:22:415206 rv = trans->RestartWithAuth(
5207 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425208 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235209
[email protected]0757e7702009-03-27 04:00:225210 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425211 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235212
5213 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505214 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235215 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5216 EXPECT_EQ(100, response->headers->GetContentLength());
5217 }
5218}
[email protected]89ceba9a2009-03-21 03:46:065219
[email protected]3c32c5f2010-05-18 15:18:125220// Tests that nonce count increments when multiple auth attempts
5221// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025222TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445223 HttpAuthHandlerDigest::Factory* digest_factory =
5224 new HttpAuthHandlerDigest::Factory();
5225 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5226 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5227 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075228 session_deps_.http_auth_handler_factory.reset(digest_factory);
5229 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125230
5231 // Transaction 1: authenticate (foo, bar) on MyRealm1
5232 {
[email protected]3c32c5f2010-05-18 15:18:125233 HttpRequestInfo request;
5234 request.method = "GET";
5235 request.url = GURL("http://www.google.com/x/y/z");
5236 request.load_flags = 0;
5237
[email protected]262eec82013-03-19 21:01:365238 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275240
[email protected]3c32c5f2010-05-18 15:18:125241 MockWrite data_writes1[] = {
5242 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5243 "Host: www.google.com\r\n"
5244 "Connection: keep-alive\r\n\r\n"),
5245 };
5246
5247 MockRead data_reads1[] = {
5248 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5249 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5250 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065251 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125252 };
5253
5254 // Resend with authorization (username=foo, password=bar)
5255 MockWrite data_writes2[] = {
5256 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5257 "Host: www.google.com\r\n"
5258 "Connection: keep-alive\r\n"
5259 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5260 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5261 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5262 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5263 };
5264
5265 // Sever accepts the authorization.
5266 MockRead data_reads2[] = {
5267 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065268 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125269 };
5270
5271 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5272 data_writes1, arraysize(data_writes1));
5273 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5274 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075275 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5276 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125277
[email protected]49639fa2011-12-20 23:22:415278 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125279
[email protected]49639fa2011-12-20 23:22:415280 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125281 EXPECT_EQ(ERR_IO_PENDING, rv);
5282
5283 rv = callback1.WaitForResult();
5284 EXPECT_EQ(OK, rv);
5285
5286 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(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125289
[email protected]49639fa2011-12-20 23:22:415290 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125291
[email protected]49639fa2011-12-20 23:22:415292 rv = trans->RestartWithAuth(
5293 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125294 EXPECT_EQ(ERR_IO_PENDING, rv);
5295
5296 rv = callback2.WaitForResult();
5297 EXPECT_EQ(OK, rv);
5298
5299 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505300 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125301 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5302 }
5303
5304 // ------------------------------------------------------------------------
5305
5306 // Transaction 2: Request another resource in digestive's protection space.
5307 // This will preemptively add an Authorization header which should have an
5308 // "nc" value of 2 (as compared to 1 in the first use.
5309 {
[email protected]3c32c5f2010-05-18 15:18:125310 HttpRequestInfo request;
5311 request.method = "GET";
5312 // Note that Transaction 1 was at /x/y/z, so this is in the same
5313 // protection space as digest.
5314 request.url = GURL("http://www.google.com/x/y/a/b");
5315 request.load_flags = 0;
5316
[email protected]262eec82013-03-19 21:01:365317 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505318 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275319
[email protected]3c32c5f2010-05-18 15:18:125320 MockWrite data_writes1[] = {
5321 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5322 "Host: www.google.com\r\n"
5323 "Connection: keep-alive\r\n"
5324 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5325 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5326 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5327 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5328 };
5329
5330 // Sever accepts the authorization.
5331 MockRead data_reads1[] = {
5332 MockRead("HTTP/1.0 200 OK\r\n"),
5333 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065334 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125335 };
5336
5337 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5338 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075339 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125340
[email protected]49639fa2011-12-20 23:22:415341 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125342
[email protected]49639fa2011-12-20 23:22:415343 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125344 EXPECT_EQ(ERR_IO_PENDING, rv);
5345
5346 rv = callback1.WaitForResult();
5347 EXPECT_EQ(OK, rv);
5348
5349 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505350 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125351 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5352 }
5353}
5354
[email protected]89ceba9a2009-03-21 03:46:065355// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025356TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065357 // Create a transaction (the dependencies aren't important).
[email protected]d207a5f2009-06-04 05:28:405358 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:365359 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075360 CreateSession(&session_deps_)));
[email protected]89ceba9a2009-03-21 03:46:065361
5362 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065363 trans->read_buf_ = new IOBuffer(15);
5364 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205365 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065366
5367 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145368 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575369 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085370 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575371 response->response_time = base::Time::Now();
5372 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065373
5374 { // Setup state for response_.vary_data
5375 HttpRequestInfo request;
5376 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5377 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275378 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435379 request.extra_headers.SetHeader("Foo", "1");
5380 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505381 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065382 }
5383
5384 // Cause the above state to be reset.
5385 trans->ResetStateForRestart();
5386
5387 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075388 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065389 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205390 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575391 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5392 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045393 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085394 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575395 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065396}
5397
[email protected]bacff652009-03-31 17:50:335398// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025399TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335400 HttpRequestInfo request;
5401 request.method = "GET";
5402 request.url = GURL("https://www.google.com/");
5403 request.load_flags = 0;
5404
[email protected]cb9bf6ca2011-01-28 13:15:275405 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365406 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075407 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:275408
[email protected]bacff652009-03-31 17:50:335409 MockWrite data_writes[] = {
5410 MockWrite("GET / HTTP/1.1\r\n"
5411 "Host: www.google.com\r\n"
5412 "Connection: keep-alive\r\n\r\n"),
5413 };
5414
5415 MockRead data_reads[] = {
5416 MockRead("HTTP/1.0 200 OK\r\n"),
5417 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5418 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065419 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335420 };
5421
[email protected]5ecc992a42009-11-11 01:41:595422 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395423 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5424 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065425 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5426 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335427
[email protected]bb88e1d32013-05-03 23:11:075428 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5429 session_deps_.socket_factory->AddSocketDataProvider(&data);
5430 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335432
[email protected]49639fa2011-12-20 23:22:415433 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335434
[email protected]49639fa2011-12-20 23:22:415435 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335436 EXPECT_EQ(ERR_IO_PENDING, rv);
5437
5438 rv = callback.WaitForResult();
5439 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5440
[email protected]49639fa2011-12-20 23:22:415441 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335442 EXPECT_EQ(ERR_IO_PENDING, rv);
5443
5444 rv = callback.WaitForResult();
5445 EXPECT_EQ(OK, rv);
5446
5447 const HttpResponseInfo* response = trans->GetResponseInfo();
5448
[email protected]fe2255a2011-09-20 19:37:505449 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335450 EXPECT_EQ(100, response->headers->GetContentLength());
5451}
5452
5453// Test HTTPS connections to a site with a bad certificate, going through a
5454// proxy
[email protected]23e482282013-06-14 16:08:025455TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075456 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335457
5458 HttpRequestInfo request;
5459 request.method = "GET";
5460 request.url = GURL("https://www.google.com/");
5461 request.load_flags = 0;
5462
5463 MockWrite proxy_writes[] = {
5464 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455465 "Host: www.google.com\r\n"
5466 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335467 };
5468
5469 MockRead proxy_reads[] = {
5470 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065471 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335472 };
5473
5474 MockWrite data_writes[] = {
5475 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455476 "Host: www.google.com\r\n"
5477 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335478 MockWrite("GET / HTTP/1.1\r\n"
5479 "Host: www.google.com\r\n"
5480 "Connection: keep-alive\r\n\r\n"),
5481 };
5482
5483 MockRead data_reads[] = {
5484 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5485 MockRead("HTTP/1.0 200 OK\r\n"),
5486 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5487 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065488 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335489 };
5490
[email protected]31a2bfe2010-02-09 08:03:395491 StaticSocketDataProvider ssl_bad_certificate(
5492 proxy_reads, arraysize(proxy_reads),
5493 proxy_writes, arraysize(proxy_writes));
5494 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5495 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065496 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5497 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335498
[email protected]bb88e1d32013-05-03 23:11:075499 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5500 session_deps_.socket_factory->AddSocketDataProvider(&data);
5501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335503
[email protected]49639fa2011-12-20 23:22:415504 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335505
5506 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075507 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335508
[email protected]d207a5f2009-06-04 05:28:405509 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365510 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075511 CreateSession(&session_deps_)));
[email protected]bacff652009-03-31 17:50:335512
[email protected]49639fa2011-12-20 23:22:415513 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335514 EXPECT_EQ(ERR_IO_PENDING, rv);
5515
5516 rv = callback.WaitForResult();
5517 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5518
[email protected]49639fa2011-12-20 23:22:415519 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335520 EXPECT_EQ(ERR_IO_PENDING, rv);
5521
5522 rv = callback.WaitForResult();
5523 EXPECT_EQ(OK, rv);
5524
5525 const HttpResponseInfo* response = trans->GetResponseInfo();
5526
[email protected]fe2255a2011-09-20 19:37:505527 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335528 EXPECT_EQ(100, response->headers->GetContentLength());
5529 }
5530}
5531
[email protected]2df19bb2010-08-25 20:13:465532
5533// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025534TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075535 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205536 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5537 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075538 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465539
5540 HttpRequestInfo request;
5541 request.method = "GET";
5542 request.url = GURL("https://www.google.com/");
5543 request.load_flags = 0;
5544
5545 MockWrite data_writes[] = {
5546 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5547 "Host: www.google.com\r\n"
5548 "Proxy-Connection: keep-alive\r\n\r\n"),
5549 MockWrite("GET / HTTP/1.1\r\n"
5550 "Host: www.google.com\r\n"
5551 "Connection: keep-alive\r\n\r\n"),
5552 };
5553
5554 MockRead data_reads[] = {
5555 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5556 MockRead("HTTP/1.1 200 OK\r\n"),
5557 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5558 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065559 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465560 };
5561
5562 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5563 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065564 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5565 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465566
[email protected]bb88e1d32013-05-03 23:11:075567 session_deps_.socket_factory->AddSocketDataProvider(&data);
5568 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5569 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465570
[email protected]49639fa2011-12-20 23:22:415571 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465572
5573 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365574 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075575 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:465576
[email protected]49639fa2011-12-20 23:22:415577 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465578 EXPECT_EQ(ERR_IO_PENDING, rv);
5579
5580 rv = callback.WaitForResult();
5581 EXPECT_EQ(OK, rv);
5582 const HttpResponseInfo* response = trans->GetResponseInfo();
5583
[email protected]fe2255a2011-09-20 19:37:505584 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465585
5586 EXPECT_TRUE(response->headers->IsKeepAlive());
5587 EXPECT_EQ(200, response->headers->response_code());
5588 EXPECT_EQ(100, response->headers->GetContentLength());
5589 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205590
5591 LoadTimingInfo load_timing_info;
5592 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5593 TestLoadTimingNotReusedWithPac(load_timing_info,
5594 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465595}
5596
[email protected]511f6f52010-12-17 03:58:295597// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025598TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075599 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205600 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5601 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075602 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295603
5604 HttpRequestInfo request;
5605 request.method = "GET";
5606 request.url = GURL("https://www.google.com/");
5607 request.load_flags = 0;
5608
5609 MockWrite data_writes[] = {
5610 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5611 "Host: www.google.com\r\n"
5612 "Proxy-Connection: keep-alive\r\n\r\n"),
5613 };
5614
5615 MockRead data_reads[] = {
5616 MockRead("HTTP/1.1 302 Redirect\r\n"),
5617 MockRead("Location: http://login.example.com/\r\n"),
5618 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065619 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295620 };
5621
5622 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5623 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065624 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295625
[email protected]bb88e1d32013-05-03 23:11:075626 session_deps_.socket_factory->AddSocketDataProvider(&data);
5627 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295628
[email protected]49639fa2011-12-20 23:22:415629 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295630
5631 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365632 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075633 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295634
[email protected]49639fa2011-12-20 23:22:415635 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295636 EXPECT_EQ(ERR_IO_PENDING, rv);
5637
5638 rv = callback.WaitForResult();
5639 EXPECT_EQ(OK, rv);
5640 const HttpResponseInfo* response = trans->GetResponseInfo();
5641
[email protected]fe2255a2011-09-20 19:37:505642 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295643
5644 EXPECT_EQ(302, response->headers->response_code());
5645 std::string url;
5646 EXPECT_TRUE(response->headers->IsRedirect(&url));
5647 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205648
5649 // In the case of redirects from proxies, HttpNetworkTransaction returns
5650 // timing for the proxy connection instead of the connection to the host,
5651 // and no send / receive times.
5652 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5653 LoadTimingInfo load_timing_info;
5654 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5655
5656 EXPECT_FALSE(load_timing_info.socket_reused);
5657 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5658
5659 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5660 EXPECT_LE(load_timing_info.proxy_resolve_start,
5661 load_timing_info.proxy_resolve_end);
5662 EXPECT_LE(load_timing_info.proxy_resolve_end,
5663 load_timing_info.connect_timing.connect_start);
5664 ExpectConnectTimingHasTimes(
5665 load_timing_info.connect_timing,
5666 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5667
5668 EXPECT_TRUE(load_timing_info.send_start.is_null());
5669 EXPECT_TRUE(load_timing_info.send_end.is_null());
5670 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:295671}
5672
5673// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025674TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075675 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295676 ProxyService::CreateFixed("https://proxy:70"));
5677
5678 HttpRequestInfo request;
5679 request.method = "GET";
5680 request.url = GURL("https://www.google.com/");
5681 request.load_flags = 0;
5682
[email protected]9075f51c2013-08-15 17:53:545683 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5684 LOWEST));
[email protected]c10b20852013-05-15 21:29:205685 scoped_ptr<SpdyFrame> goaway(
5686 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295687 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065688 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:125689 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295690 };
5691
5692 static const char* const kExtraHeaders[] = {
5693 "location",
5694 "http://login.example.com/",
5695 };
[email protected]ff98d7f02012-03-22 21:44:195696 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025697 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295698 arraysize(kExtraHeaders)/2, 1));
5699 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065700 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5701 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:295702 };
5703
[email protected]dd54bd82012-07-19 23:44:575704 DelayedSocketData data(
5705 1, // wait for one write to finish before reading.
5706 data_reads, arraysize(data_reads),
5707 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065708 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025709 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295710
[email protected]bb88e1d32013-05-03 23:11:075711 session_deps_.socket_factory->AddSocketDataProvider(&data);
5712 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295713
[email protected]49639fa2011-12-20 23:22:415714 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295715
5716 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365717 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075718 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295719
[email protected]49639fa2011-12-20 23:22:415720 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295721 EXPECT_EQ(ERR_IO_PENDING, rv);
5722
5723 rv = callback.WaitForResult();
5724 EXPECT_EQ(OK, rv);
5725 const HttpResponseInfo* response = trans->GetResponseInfo();
5726
[email protected]fe2255a2011-09-20 19:37:505727 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295728
5729 EXPECT_EQ(302, response->headers->response_code());
5730 std::string url;
5731 EXPECT_TRUE(response->headers->IsRedirect(&url));
5732 EXPECT_EQ("http://login.example.com/", url);
5733}
5734
[email protected]4eddbc732012-08-09 05:40:175735// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025736TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175737 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075738 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295739 ProxyService::CreateFixed("https://proxy:70"));
5740
5741 HttpRequestInfo request;
5742 request.method = "GET";
5743 request.url = GURL("https://www.google.com/");
5744 request.load_flags = 0;
5745
5746 MockWrite data_writes[] = {
5747 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5748 "Host: www.google.com\r\n"
5749 "Proxy-Connection: keep-alive\r\n\r\n"),
5750 };
5751
5752 MockRead data_reads[] = {
5753 MockRead("HTTP/1.1 404 Not Found\r\n"),
5754 MockRead("Content-Length: 23\r\n\r\n"),
5755 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:065756 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295757 };
5758
5759 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5760 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065761 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295762
[email protected]bb88e1d32013-05-03 23:11:075763 session_deps_.socket_factory->AddSocketDataProvider(&data);
5764 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295765
[email protected]49639fa2011-12-20 23:22:415766 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295767
5768 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365769 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075770 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295771
[email protected]49639fa2011-12-20 23:22:415772 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295773 EXPECT_EQ(ERR_IO_PENDING, rv);
5774
5775 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175776 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295777
[email protected]4eddbc732012-08-09 05:40:175778 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295779}
5780
[email protected]4eddbc732012-08-09 05:40:175781// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025782TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175783 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075784 session_deps_.proxy_service.reset(
5785 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:295786
5787 HttpRequestInfo request;
5788 request.method = "GET";
5789 request.url = GURL("https://www.google.com/");
5790 request.load_flags = 0;
5791
[email protected]9075f51c2013-08-15 17:53:545792 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5793 LOWEST));
[email protected]c10b20852013-05-15 21:29:205794 scoped_ptr<SpdyFrame> rst(
5795 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295796 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065797 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175798 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295799 };
5800
5801 static const char* const kExtraHeaders[] = {
5802 "location",
5803 "http://login.example.com/",
5804 };
[email protected]ff98d7f02012-03-22 21:44:195805 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025806 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295807 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:195808 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:025809 spdy_util_.ConstructSpdyBodyFrame(
5810 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:295811 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065812 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5813 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175814 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:295815 };
5816
[email protected]dd54bd82012-07-19 23:44:575817 DelayedSocketData data(
5818 1, // wait for one write to finish before reading.
5819 data_reads, arraysize(data_reads),
5820 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065821 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025822 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295823
[email protected]bb88e1d32013-05-03 23:11:075824 session_deps_.socket_factory->AddSocketDataProvider(&data);
5825 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295826
[email protected]49639fa2011-12-20 23:22:415827 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295828
5829 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365830 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075831 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295832
[email protected]49639fa2011-12-20 23:22:415833 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295834 EXPECT_EQ(ERR_IO_PENDING, rv);
5835
5836 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175837 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295838
[email protected]4eddbc732012-08-09 05:40:175839 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295840}
5841
[email protected]0c5fb722012-02-28 11:50:355842// Test the request-challenge-retry sequence for basic auth, through
5843// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:025844TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:355845 HttpRequestInfo request;
5846 request.method = "GET";
5847 request.url = GURL("https://www.google.com/");
5848 // when the no authentication data flag is set.
5849 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
5850
5851 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075852 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205853 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:295854 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075855 session_deps_.net_log = log.bound().net_log();
5856 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:355857
5858 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:545859 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5860 LOWEST));
[email protected]c10b20852013-05-15 21:29:205861 scoped_ptr<SpdyFrame> rst(
5862 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:355863
5864 // After calling trans->RestartWithAuth(), this is the request we should
5865 // be issuing -- the final header line contains the credentials.
5866 const char* const kAuthCredentials[] = {
5867 "proxy-authorization", "Basic Zm9vOmJhcg==",
5868 };
[email protected]fba2dbde2013-05-24 16:09:015869 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:545870 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:355871 // fetch https://www.google.com/ via HTTP
5872 const char get[] = "GET / HTTP/1.1\r\n"
5873 "Host: www.google.com\r\n"
5874 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:195875 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:025876 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:355877
5878 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:205879 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:215880 CreateMockWrite(*rst, 4, ASYNC),
5881 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:205882 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:355883 };
5884
5885 // The proxy responds to the connect with a 407, using a persistent
5886 // connection.
5887 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:025888 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
5889 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:355890 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
5891 };
5892
[email protected]ff98d7f02012-03-22 21:44:195893 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:235894 spdy_util_.ConstructSpdyControlFrame(NULL,
5895 0,
5896 false,
5897 1,
5898 LOWEST,
5899 SYN_REPLY,
5900 CONTROL_FLAG_NONE,
5901 kAuthChallenge,
5902 arraysize(kAuthChallenge),
5903 0));
[email protected]0c5fb722012-02-28 11:50:355904
[email protected]23e482282013-06-14 16:08:025905 scoped_ptr<SpdyFrame> conn_resp(
5906 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:355907 const char resp[] = "HTTP/1.1 200 OK\r\n"
5908 "Content-Length: 5\r\n\r\n";
5909
[email protected]ff98d7f02012-03-22 21:44:195910 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025911 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:195912 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:025913 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:355914 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:205915 CreateMockRead(*conn_auth_resp, 2, ASYNC),
5916 CreateMockRead(*conn_resp, 6, ASYNC),
5917 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
5918 CreateMockRead(*wrapped_body, 10, ASYNC),
5919 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:355920 };
5921
[email protected]dd54bd82012-07-19 23:44:575922 OrderedSocketData spdy_data(
5923 spdy_reads, arraysize(spdy_reads),
5924 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075925 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:355926 // Negotiate SPDY to the proxy
5927 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:025928 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:075929 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:355930 // Vanilla SSL to the server
5931 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075932 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:355933
5934 TestCompletionCallback callback1;
5935
[email protected]262eec82013-03-19 21:01:365936 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505937 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:355938
5939 int rv = trans->Start(&request, callback1.callback(), log.bound());
5940 EXPECT_EQ(ERR_IO_PENDING, rv);
5941
5942 rv = callback1.WaitForResult();
5943 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:575944 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:355945 log.GetEntries(&entries);
5946 size_t pos = ExpectLogContainsSomewhere(
5947 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
5948 NetLog::PHASE_NONE);
5949 ExpectLogContainsSomewhere(
5950 entries, pos,
5951 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
5952 NetLog::PHASE_NONE);
5953
5954 const HttpResponseInfo* response = trans->GetResponseInfo();
5955 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505956 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:355957 EXPECT_EQ(407, response->headers->response_code());
5958 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5959 EXPECT_TRUE(response->auth_challenge.get() != NULL);
5960 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5961
5962 TestCompletionCallback callback2;
5963
5964 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
5965 callback2.callback());
5966 EXPECT_EQ(ERR_IO_PENDING, rv);
5967
5968 rv = callback2.WaitForResult();
5969 EXPECT_EQ(OK, rv);
5970
5971 response = trans->GetResponseInfo();
5972 ASSERT_TRUE(response != NULL);
5973
5974 EXPECT_TRUE(response->headers->IsKeepAlive());
5975 EXPECT_EQ(200, response->headers->response_code());
5976 EXPECT_EQ(5, response->headers->GetContentLength());
5977 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5978
5979 // The password prompt info should not be set.
5980 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5981
[email protected]029c83b62013-01-24 05:28:205982 LoadTimingInfo load_timing_info;
5983 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5984 TestLoadTimingNotReusedWithPac(load_timing_info,
5985 CONNECT_TIMING_HAS_SSL_TIMES);
5986
[email protected]0c5fb722012-02-28 11:50:355987 trans.reset();
5988 session->CloseAllConnections();
5989}
5990
[email protected]7c6f7ba2012-04-03 04:09:295991// Test that an explicitly trusted SPDY proxy can push a resource from an
5992// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:025993TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:295994 HttpRequestInfo request;
5995 HttpRequestInfo push_request;
5996
[email protected]7c6f7ba2012-04-03 04:09:295997 request.method = "GET";
5998 request.url = GURL("http://www.google.com/");
5999 push_request.method = "GET";
6000 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6001
[email protected]7c6f7ba2012-04-03 04:09:296002 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076003 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206004 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296005 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076006 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506007
6008 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076009 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506010
[email protected]bb88e1d32013-05-03 23:11:076011 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296012
[email protected]cdf8f7e72013-05-23 10:56:466013 scoped_ptr<SpdyFrame> stream1_syn(
6014 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296015
6016 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466017 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296018 };
6019
6020 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026021 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296022
6023 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026024 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296025
6026 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026027 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296028 0,
6029 2,
6030 1,
6031 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436032 const char kPushedData[] = "pushed";
6033 scoped_ptr<SpdyFrame> stream2_body(
6034 spdy_util_.ConstructSpdyBodyFrame(
6035 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296036
6037 MockRead spdy_reads[] = {
6038 CreateMockRead(*stream1_reply, 2, ASYNC),
6039 CreateMockRead(*stream2_syn, 3, ASYNC),
6040 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436041 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296042 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6043 };
6044
[email protected]dd54bd82012-07-19 23:44:576045 OrderedSocketData spdy_data(
6046 spdy_reads, arraysize(spdy_reads),
6047 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076048 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296049 // Negotiate SPDY to the proxy
6050 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026051 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076052 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296053
[email protected]262eec82013-03-19 21:01:366054 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296056 TestCompletionCallback callback;
6057 int rv = trans->Start(&request, callback.callback(), log.bound());
6058 EXPECT_EQ(ERR_IO_PENDING, rv);
6059
6060 rv = callback.WaitForResult();
6061 EXPECT_EQ(OK, rv);
6062 const HttpResponseInfo* response = trans->GetResponseInfo();
6063
[email protected]262eec82013-03-19 21:01:366064 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6066 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296067 EXPECT_EQ(ERR_IO_PENDING, rv);
6068
6069 rv = callback.WaitForResult();
6070 EXPECT_EQ(OK, rv);
6071 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6072
6073 ASSERT_TRUE(response != NULL);
6074 EXPECT_TRUE(response->headers->IsKeepAlive());
6075
6076 EXPECT_EQ(200, response->headers->response_code());
6077 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6078
6079 std::string response_data;
6080 rv = ReadTransaction(trans.get(), &response_data);
6081 EXPECT_EQ(OK, rv);
6082 EXPECT_EQ("hello!", response_data);
6083
[email protected]029c83b62013-01-24 05:28:206084 LoadTimingInfo load_timing_info;
6085 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6086 TestLoadTimingNotReusedWithPac(load_timing_info,
6087 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6088
[email protected]7c6f7ba2012-04-03 04:09:296089 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506090 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296091 EXPECT_EQ(200, push_response->headers->response_code());
6092
6093 rv = ReadTransaction(push_trans.get(), &response_data);
6094 EXPECT_EQ(OK, rv);
6095 EXPECT_EQ("pushed", response_data);
6096
[email protected]029c83b62013-01-24 05:28:206097 LoadTimingInfo push_load_timing_info;
6098 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6099 TestLoadTimingReusedWithPac(push_load_timing_info);
6100 // The transactions should share a socket ID, despite being for different
6101 // origins.
6102 EXPECT_EQ(load_timing_info.socket_log_id,
6103 push_load_timing_info.socket_log_id);
6104
[email protected]7c6f7ba2012-04-03 04:09:296105 trans.reset();
6106 push_trans.reset();
6107 session->CloseAllConnections();
6108}
6109
[email protected]8c843192012-04-05 07:15:006110// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026111TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006112 HttpRequestInfo request;
6113
6114 request.method = "GET";
6115 request.url = GURL("http://www.google.com/");
6116
[email protected]8c843192012-04-05 07:15:006117 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076118 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006119 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296120 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076121 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506122
6123 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076124 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506125
[email protected]bb88e1d32013-05-03 23:11:076126 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006127
[email protected]cdf8f7e72013-05-23 10:56:466128 scoped_ptr<SpdyFrame> stream1_syn(
6129 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006130
6131 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206132 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006133
6134 MockWrite spdy_writes[] = {
6135 CreateMockWrite(*stream1_syn, 1, ASYNC),
6136 CreateMockWrite(*push_rst, 4),
6137 };
6138
6139 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026140 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006141
6142 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026143 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006144
6145 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026146 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006147 0,
6148 2,
6149 1,
6150 "https://www.another-origin.com/foo.dat"));
6151
6152 MockRead spdy_reads[] = {
6153 CreateMockRead(*stream1_reply, 2, ASYNC),
6154 CreateMockRead(*stream2_syn, 3, ASYNC),
6155 CreateMockRead(*stream1_body, 5, ASYNC),
6156 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6157 };
6158
[email protected]dd54bd82012-07-19 23:44:576159 OrderedSocketData spdy_data(
6160 spdy_reads, arraysize(spdy_reads),
6161 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076162 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006163 // Negotiate SPDY to the proxy
6164 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026165 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076166 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006167
[email protected]262eec82013-03-19 21:01:366168 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006170 TestCompletionCallback callback;
6171 int rv = trans->Start(&request, callback.callback(), log.bound());
6172 EXPECT_EQ(ERR_IO_PENDING, rv);
6173
6174 rv = callback.WaitForResult();
6175 EXPECT_EQ(OK, rv);
6176 const HttpResponseInfo* response = trans->GetResponseInfo();
6177
6178 ASSERT_TRUE(response != NULL);
6179 EXPECT_TRUE(response->headers->IsKeepAlive());
6180
6181 EXPECT_EQ(200, response->headers->response_code());
6182 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6183
6184 std::string response_data;
6185 rv = ReadTransaction(trans.get(), &response_data);
6186 EXPECT_EQ(OK, rv);
6187 EXPECT_EQ("hello!", response_data);
6188
6189 trans.reset();
6190 session->CloseAllConnections();
6191}
6192
[email protected]2df19bb2010-08-25 20:13:466193// Test HTTPS connections to a site with a bad certificate, going through an
6194// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026195TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076196 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116197 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466198
6199 HttpRequestInfo request;
6200 request.method = "GET";
6201 request.url = GURL("https://www.google.com/");
6202 request.load_flags = 0;
6203
6204 // Attempt to fetch the URL from a server with a bad cert
6205 MockWrite bad_cert_writes[] = {
6206 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6207 "Host: www.google.com\r\n"
6208 "Proxy-Connection: keep-alive\r\n\r\n"),
6209 };
6210
6211 MockRead bad_cert_reads[] = {
6212 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066213 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466214 };
6215
6216 // Attempt to fetch the URL with a good cert
6217 MockWrite good_data_writes[] = {
6218 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6219 "Host: www.google.com\r\n"
6220 "Proxy-Connection: keep-alive\r\n\r\n"),
6221 MockWrite("GET / HTTP/1.1\r\n"
6222 "Host: www.google.com\r\n"
6223 "Connection: keep-alive\r\n\r\n"),
6224 };
6225
6226 MockRead good_cert_reads[] = {
6227 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6228 MockRead("HTTP/1.0 200 OK\r\n"),
6229 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6230 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066231 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466232 };
6233
6234 StaticSocketDataProvider ssl_bad_certificate(
6235 bad_cert_reads, arraysize(bad_cert_reads),
6236 bad_cert_writes, arraysize(bad_cert_writes));
6237 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6238 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066239 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6240 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466241
6242 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076243 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6244 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466246
6247 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076248 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6249 session_deps_.socket_factory->AddSocketDataProvider(&data);
6250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466251
[email protected]49639fa2011-12-20 23:22:416252 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466253
6254 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366255 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076256 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:466257
[email protected]49639fa2011-12-20 23:22:416258 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466259 EXPECT_EQ(ERR_IO_PENDING, rv);
6260
6261 rv = callback.WaitForResult();
6262 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6263
[email protected]49639fa2011-12-20 23:22:416264 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466265 EXPECT_EQ(ERR_IO_PENDING, rv);
6266
6267 rv = callback.WaitForResult();
6268 EXPECT_EQ(OK, rv);
6269
6270 const HttpResponseInfo* response = trans->GetResponseInfo();
6271
[email protected]fe2255a2011-09-20 19:37:506272 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466273 EXPECT_EQ(100, response->headers->GetContentLength());
6274}
6275
[email protected]23e482282013-06-14 16:08:026276TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426277 HttpRequestInfo request;
6278 request.method = "GET";
6279 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436280 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6281 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426282
[email protected]cb9bf6ca2011-01-28 13:15:276283 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366284 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076285 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276286
[email protected]1c773ea12009-04-28 19:58:426287 MockWrite data_writes[] = {
6288 MockWrite("GET / HTTP/1.1\r\n"
6289 "Host: www.google.com\r\n"
6290 "Connection: keep-alive\r\n"
6291 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6292 };
6293
6294 // Lastly, the server responds with the actual content.
6295 MockRead data_reads[] = {
6296 MockRead("HTTP/1.0 200 OK\r\n"),
6297 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6298 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066299 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426300 };
6301
[email protected]31a2bfe2010-02-09 08:03:396302 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6303 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076304 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426305
[email protected]49639fa2011-12-20 23:22:416306 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426307
[email protected]49639fa2011-12-20 23:22:416308 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426309 EXPECT_EQ(ERR_IO_PENDING, rv);
6310
6311 rv = callback.WaitForResult();
6312 EXPECT_EQ(OK, rv);
6313}
6314
[email protected]23e482282013-06-14 16:08:026315TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296316 HttpRequestInfo request;
6317 request.method = "GET";
6318 request.url = GURL("https://www.google.com/");
6319 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6320 "Chromium Ultra Awesome X Edition");
6321
[email protected]bb88e1d32013-05-03 23:11:076322 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:276323 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366324 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076325 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276326
[email protected]da81f132010-08-18 23:39:296327 MockWrite data_writes[] = {
6328 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6329 "Host: www.google.com\r\n"
6330 "Proxy-Connection: keep-alive\r\n"
6331 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6332 };
6333 MockRead data_reads[] = {
6334 // Return an error, so the transaction stops here (this test isn't
6335 // interested in the rest).
6336 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6337 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6338 MockRead("Proxy-Connection: close\r\n\r\n"),
6339 };
6340
6341 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6342 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076343 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296344
[email protected]49639fa2011-12-20 23:22:416345 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296346
[email protected]49639fa2011-12-20 23:22:416347 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296348 EXPECT_EQ(ERR_IO_PENDING, rv);
6349
6350 rv = callback.WaitForResult();
6351 EXPECT_EQ(OK, rv);
6352}
6353
[email protected]23e482282013-06-14 16:08:026354TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426355 HttpRequestInfo request;
6356 request.method = "GET";
6357 request.url = GURL("http://www.google.com/");
6358 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166359 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6360 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426361
[email protected]cb9bf6ca2011-01-28 13:15:276362 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366363 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076364 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276365
[email protected]1c773ea12009-04-28 19:58:426366 MockWrite data_writes[] = {
6367 MockWrite("GET / HTTP/1.1\r\n"
6368 "Host: www.google.com\r\n"
6369 "Connection: keep-alive\r\n"
6370 "Referer: http://the.previous.site.com/\r\n\r\n"),
6371 };
6372
6373 // Lastly, the server responds with the actual content.
6374 MockRead data_reads[] = {
6375 MockRead("HTTP/1.0 200 OK\r\n"),
6376 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6377 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066378 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426379 };
6380
[email protected]31a2bfe2010-02-09 08:03:396381 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6382 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076383 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426384
[email protected]49639fa2011-12-20 23:22:416385 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426386
[email protected]49639fa2011-12-20 23:22:416387 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426388 EXPECT_EQ(ERR_IO_PENDING, rv);
6389
6390 rv = callback.WaitForResult();
6391 EXPECT_EQ(OK, rv);
6392}
6393
[email protected]23e482282013-06-14 16:08:026394TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426395 HttpRequestInfo request;
6396 request.method = "POST";
6397 request.url = GURL("http://www.google.com/");
6398
[email protected]cb9bf6ca2011-01-28 13:15:276399 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366400 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076401 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276402
[email protected]1c773ea12009-04-28 19:58:426403 MockWrite data_writes[] = {
6404 MockWrite("POST / HTTP/1.1\r\n"
6405 "Host: www.google.com\r\n"
6406 "Connection: keep-alive\r\n"
6407 "Content-Length: 0\r\n\r\n"),
6408 };
6409
6410 // Lastly, the server responds with the actual content.
6411 MockRead data_reads[] = {
6412 MockRead("HTTP/1.0 200 OK\r\n"),
6413 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6414 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066415 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426416 };
6417
[email protected]31a2bfe2010-02-09 08:03:396418 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6419 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076420 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426421
[email protected]49639fa2011-12-20 23:22:416422 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426423
[email protected]49639fa2011-12-20 23:22:416424 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426425 EXPECT_EQ(ERR_IO_PENDING, rv);
6426
6427 rv = callback.WaitForResult();
6428 EXPECT_EQ(OK, rv);
6429}
6430
[email protected]23e482282013-06-14 16:08:026431TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426432 HttpRequestInfo request;
6433 request.method = "PUT";
6434 request.url = GURL("http://www.google.com/");
6435
[email protected]cb9bf6ca2011-01-28 13:15:276436 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366437 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076438 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276439
[email protected]1c773ea12009-04-28 19:58:426440 MockWrite data_writes[] = {
6441 MockWrite("PUT / HTTP/1.1\r\n"
6442 "Host: www.google.com\r\n"
6443 "Connection: keep-alive\r\n"
6444 "Content-Length: 0\r\n\r\n"),
6445 };
6446
6447 // Lastly, the server responds with the actual content.
6448 MockRead data_reads[] = {
6449 MockRead("HTTP/1.0 200 OK\r\n"),
6450 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6451 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066452 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426453 };
6454
[email protected]31a2bfe2010-02-09 08:03:396455 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6456 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076457 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426458
[email protected]49639fa2011-12-20 23:22:416459 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426460
[email protected]49639fa2011-12-20 23:22:416461 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426462 EXPECT_EQ(ERR_IO_PENDING, rv);
6463
6464 rv = callback.WaitForResult();
6465 EXPECT_EQ(OK, rv);
6466}
6467
[email protected]23e482282013-06-14 16:08:026468TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426469 HttpRequestInfo request;
6470 request.method = "HEAD";
6471 request.url = GURL("http://www.google.com/");
6472
[email protected]cb9bf6ca2011-01-28 13:15:276473 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366474 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076475 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276476
[email protected]1c773ea12009-04-28 19:58:426477 MockWrite data_writes[] = {
6478 MockWrite("HEAD / HTTP/1.1\r\n"
6479 "Host: www.google.com\r\n"
6480 "Connection: keep-alive\r\n"
6481 "Content-Length: 0\r\n\r\n"),
6482 };
6483
6484 // Lastly, the server responds with the actual content.
6485 MockRead data_reads[] = {
6486 MockRead("HTTP/1.0 200 OK\r\n"),
6487 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6488 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066489 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426490 };
6491
[email protected]31a2bfe2010-02-09 08:03:396492 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6493 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076494 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426495
[email protected]49639fa2011-12-20 23:22:416496 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426497
[email protected]49639fa2011-12-20 23:22:416498 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426499 EXPECT_EQ(ERR_IO_PENDING, rv);
6500
6501 rv = callback.WaitForResult();
6502 EXPECT_EQ(OK, rv);
6503}
6504
[email protected]23e482282013-06-14 16:08:026505TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426506 HttpRequestInfo request;
6507 request.method = "GET";
6508 request.url = GURL("http://www.google.com/");
6509 request.load_flags = LOAD_BYPASS_CACHE;
6510
[email protected]cb9bf6ca2011-01-28 13:15:276511 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366512 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076513 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276514
[email protected]1c773ea12009-04-28 19:58:426515 MockWrite data_writes[] = {
6516 MockWrite("GET / HTTP/1.1\r\n"
6517 "Host: www.google.com\r\n"
6518 "Connection: keep-alive\r\n"
6519 "Pragma: no-cache\r\n"
6520 "Cache-Control: no-cache\r\n\r\n"),
6521 };
6522
6523 // Lastly, the server responds with the actual content.
6524 MockRead data_reads[] = {
6525 MockRead("HTTP/1.0 200 OK\r\n"),
6526 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6527 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066528 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426529 };
6530
[email protected]31a2bfe2010-02-09 08:03:396531 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6532 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076533 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426534
[email protected]49639fa2011-12-20 23:22:416535 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426536
[email protected]49639fa2011-12-20 23:22:416537 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426538 EXPECT_EQ(ERR_IO_PENDING, rv);
6539
6540 rv = callback.WaitForResult();
6541 EXPECT_EQ(OK, rv);
6542}
6543
[email protected]23e482282013-06-14 16:08:026544TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426545 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426546 HttpRequestInfo request;
6547 request.method = "GET";
6548 request.url = GURL("http://www.google.com/");
6549 request.load_flags = LOAD_VALIDATE_CACHE;
6550
[email protected]cb9bf6ca2011-01-28 13:15:276551 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366552 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076553 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276554
[email protected]1c773ea12009-04-28 19:58:426555 MockWrite data_writes[] = {
6556 MockWrite("GET / HTTP/1.1\r\n"
6557 "Host: www.google.com\r\n"
6558 "Connection: keep-alive\r\n"
6559 "Cache-Control: max-age=0\r\n\r\n"),
6560 };
6561
6562 // Lastly, the server responds with the actual content.
6563 MockRead data_reads[] = {
6564 MockRead("HTTP/1.0 200 OK\r\n"),
6565 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6566 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066567 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426568 };
6569
[email protected]31a2bfe2010-02-09 08:03:396570 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6571 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076572 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426573
[email protected]49639fa2011-12-20 23:22:416574 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426575
[email protected]49639fa2011-12-20 23:22:416576 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426577 EXPECT_EQ(ERR_IO_PENDING, rv);
6578
6579 rv = callback.WaitForResult();
6580 EXPECT_EQ(OK, rv);
6581}
6582
[email protected]23e482282013-06-14 16:08:026583TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426584 HttpRequestInfo request;
6585 request.method = "GET";
6586 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436587 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426588
[email protected]cb9bf6ca2011-01-28 13:15:276589 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366590 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076591 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276592
[email protected]1c773ea12009-04-28 19:58:426593 MockWrite data_writes[] = {
6594 MockWrite("GET / HTTP/1.1\r\n"
6595 "Host: www.google.com\r\n"
6596 "Connection: keep-alive\r\n"
6597 "FooHeader: Bar\r\n\r\n"),
6598 };
6599
6600 // Lastly, the server responds with the actual content.
6601 MockRead data_reads[] = {
6602 MockRead("HTTP/1.0 200 OK\r\n"),
6603 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6604 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066605 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426606 };
6607
[email protected]31a2bfe2010-02-09 08:03:396608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6609 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426611
[email protected]49639fa2011-12-20 23:22:416612 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426613
[email protected]49639fa2011-12-20 23:22:416614 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426615 EXPECT_EQ(ERR_IO_PENDING, rv);
6616
6617 rv = callback.WaitForResult();
6618 EXPECT_EQ(OK, rv);
6619}
6620
[email protected]23e482282013-06-14 16:08:026621TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476622 HttpRequestInfo request;
6623 request.method = "GET";
6624 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436625 request.extra_headers.SetHeader("referer", "www.foo.com");
6626 request.extra_headers.SetHeader("hEllo", "Kitty");
6627 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476628
[email protected]cb9bf6ca2011-01-28 13:15:276629 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366630 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076631 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276632
[email protected]270c6412010-03-29 22:02:476633 MockWrite data_writes[] = {
6634 MockWrite("GET / HTTP/1.1\r\n"
6635 "Host: www.google.com\r\n"
6636 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166637 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476638 "hEllo: Kitty\r\n"
6639 "FoO: bar\r\n\r\n"),
6640 };
6641
6642 // Lastly, the server responds with the actual content.
6643 MockRead data_reads[] = {
6644 MockRead("HTTP/1.0 200 OK\r\n"),
6645 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6646 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066647 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476648 };
6649
6650 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6651 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076652 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:476653
[email protected]49639fa2011-12-20 23:22:416654 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:476655
[email protected]49639fa2011-12-20 23:22:416656 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:476657 EXPECT_EQ(ERR_IO_PENDING, rv);
6658
6659 rv = callback.WaitForResult();
6660 EXPECT_EQ(OK, rv);
6661}
6662
[email protected]23e482282013-06-14 16:08:026663TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276664 HttpRequestInfo request;
6665 request.method = "GET";
6666 request.url = GURL("http://www.google.com/");
6667 request.load_flags = 0;
6668
[email protected]bb88e1d32013-05-03 23:11:076669 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206670 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6671 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076672 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026673
6674 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366675 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076676 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026677
[email protected]3cd17242009-06-23 02:59:026678 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6679 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6680
6681 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066682 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026683 MockWrite("GET / HTTP/1.1\r\n"
6684 "Host: www.google.com\r\n"
6685 "Connection: keep-alive\r\n\r\n")
6686 };
6687
6688 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066689 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:026690 MockRead("HTTP/1.0 200 OK\r\n"),
6691 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6692 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066693 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026694 };
6695
[email protected]31a2bfe2010-02-09 08:03:396696 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6697 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076698 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026699
[email protected]49639fa2011-12-20 23:22:416700 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026701
[email protected]49639fa2011-12-20 23:22:416702 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026703 EXPECT_EQ(ERR_IO_PENDING, rv);
6704
6705 rv = callback.WaitForResult();
6706 EXPECT_EQ(OK, rv);
6707
6708 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506709 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026710
[email protected]029c83b62013-01-24 05:28:206711 LoadTimingInfo load_timing_info;
6712 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6713 TestLoadTimingNotReusedWithPac(load_timing_info,
6714 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6715
[email protected]3cd17242009-06-23 02:59:026716 std::string response_text;
6717 rv = ReadTransaction(trans.get(), &response_text);
6718 EXPECT_EQ(OK, rv);
6719 EXPECT_EQ("Payload", response_text);
6720}
6721
[email protected]23e482282013-06-14 16:08:026722TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276723 HttpRequestInfo request;
6724 request.method = "GET";
6725 request.url = GURL("https://www.google.com/");
6726 request.load_flags = 0;
6727
[email protected]bb88e1d32013-05-03 23:11:076728 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206729 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6730 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076731 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026732
6733 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366734 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076735 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026736
[email protected]3cd17242009-06-23 02:59:026737 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6738 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6739
6740 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066741 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:356742 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026743 MockWrite("GET / HTTP/1.1\r\n"
6744 "Host: www.google.com\r\n"
6745 "Connection: keep-alive\r\n\r\n")
6746 };
6747
6748 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016749 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6750 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:356751 MockRead("HTTP/1.0 200 OK\r\n"),
6752 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6753 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066754 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356755 };
6756
[email protected]31a2bfe2010-02-09 08:03:396757 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6758 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076759 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356760
[email protected]8ddf8322012-02-23 18:08:066761 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:356763
[email protected]49639fa2011-12-20 23:22:416764 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356765
[email protected]49639fa2011-12-20 23:22:416766 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356767 EXPECT_EQ(ERR_IO_PENDING, rv);
6768
6769 rv = callback.WaitForResult();
6770 EXPECT_EQ(OK, rv);
6771
[email protected]029c83b62013-01-24 05:28:206772 LoadTimingInfo load_timing_info;
6773 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6774 TestLoadTimingNotReusedWithPac(load_timing_info,
6775 CONNECT_TIMING_HAS_SSL_TIMES);
6776
[email protected]e0c27be2009-07-15 13:09:356777 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506778 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356779
6780 std::string response_text;
6781 rv = ReadTransaction(trans.get(), &response_text);
6782 EXPECT_EQ(OK, rv);
6783 EXPECT_EQ("Payload", response_text);
6784}
6785
[email protected]23e482282013-06-14 16:08:026786TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:206787 HttpRequestInfo request;
6788 request.method = "GET";
6789 request.url = GURL("http://www.google.com/");
6790 request.load_flags = 0;
6791
[email protected]bb88e1d32013-05-03 23:11:076792 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206793 ProxyService::CreateFixed("socks4://myproxy:1080"));
6794 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076795 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:206796
6797 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366798 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076799 CreateSession(&session_deps_)));
[email protected]029c83b62013-01-24 05:28:206800
6801 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6802 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6803
6804 MockWrite data_writes[] = {
6805 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6806 MockWrite("GET / HTTP/1.1\r\n"
6807 "Host: www.google.com\r\n"
6808 "Connection: keep-alive\r\n\r\n")
6809 };
6810
6811 MockRead data_reads[] = {
6812 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6813 MockRead("HTTP/1.0 200 OK\r\n"),
6814 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6815 MockRead("Payload"),
6816 MockRead(SYNCHRONOUS, OK)
6817 };
6818
6819 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6820 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076821 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:206822
6823 TestCompletionCallback callback;
6824
6825 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6826 EXPECT_EQ(ERR_IO_PENDING, rv);
6827
6828 rv = callback.WaitForResult();
6829 EXPECT_EQ(OK, rv);
6830
6831 const HttpResponseInfo* response = trans->GetResponseInfo();
6832 ASSERT_TRUE(response != NULL);
6833
6834 LoadTimingInfo load_timing_info;
6835 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6836 TestLoadTimingNotReused(load_timing_info,
6837 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6838
6839 std::string response_text;
6840 rv = ReadTransaction(trans.get(), &response_text);
6841 EXPECT_EQ(OK, rv);
6842 EXPECT_EQ("Payload", response_text);
6843}
6844
[email protected]23e482282013-06-14 16:08:026845TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276846 HttpRequestInfo request;
6847 request.method = "GET";
6848 request.url = GURL("http://www.google.com/");
6849 request.load_flags = 0;
6850
[email protected]bb88e1d32013-05-03 23:11:076851 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206852 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6853 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076854 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356855
6856 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366857 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076858 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356859
[email protected]e0c27be2009-07-15 13:09:356860 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6861 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376862 const char kSOCKS5OkRequest[] = {
6863 0x05, // Version
6864 0x01, // Command (CONNECT)
6865 0x00, // Reserved.
6866 0x03, // Address type (DOMAINNAME).
6867 0x0E, // Length of domain (14)
6868 // Domain string:
6869 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6870 0x00, 0x50, // 16-bit port (80)
6871 };
[email protected]e0c27be2009-07-15 13:09:356872 const char kSOCKS5OkResponse[] =
6873 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
6874
6875 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066876 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6877 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:356878 MockWrite("GET / HTTP/1.1\r\n"
6879 "Host: www.google.com\r\n"
6880 "Connection: keep-alive\r\n\r\n")
6881 };
6882
6883 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016884 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6885 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:356886 MockRead("HTTP/1.0 200 OK\r\n"),
6887 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6888 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066889 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356890 };
6891
[email protected]31a2bfe2010-02-09 08:03:396892 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6893 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076894 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356895
[email protected]49639fa2011-12-20 23:22:416896 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356897
[email protected]49639fa2011-12-20 23:22:416898 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356899 EXPECT_EQ(ERR_IO_PENDING, rv);
6900
6901 rv = callback.WaitForResult();
6902 EXPECT_EQ(OK, rv);
6903
6904 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506905 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356906
[email protected]029c83b62013-01-24 05:28:206907 LoadTimingInfo load_timing_info;
6908 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6909 TestLoadTimingNotReusedWithPac(load_timing_info,
6910 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6911
[email protected]e0c27be2009-07-15 13:09:356912 std::string response_text;
6913 rv = ReadTransaction(trans.get(), &response_text);
6914 EXPECT_EQ(OK, rv);
6915 EXPECT_EQ("Payload", response_text);
6916}
6917
[email protected]23e482282013-06-14 16:08:026918TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276919 HttpRequestInfo request;
6920 request.method = "GET";
6921 request.url = GURL("https://www.google.com/");
6922 request.load_flags = 0;
6923
[email protected]bb88e1d32013-05-03 23:11:076924 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206925 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6926 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076927 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356928
6929 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366930 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076931 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356932
[email protected]e0c27be2009-07-15 13:09:356933 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6934 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376935 const unsigned char kSOCKS5OkRequest[] = {
6936 0x05, // Version
6937 0x01, // Command (CONNECT)
6938 0x00, // Reserved.
6939 0x03, // Address type (DOMAINNAME).
6940 0x0E, // Length of domain (14)
6941 // Domain string:
6942 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6943 0x01, 0xBB, // 16-bit port (443)
6944 };
6945
[email protected]e0c27be2009-07-15 13:09:356946 const char kSOCKS5OkResponse[] =
6947 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
6948
6949 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066950 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6951 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:356952 arraysize(kSOCKS5OkRequest)),
6953 MockWrite("GET / HTTP/1.1\r\n"
6954 "Host: www.google.com\r\n"
6955 "Connection: keep-alive\r\n\r\n")
6956 };
6957
6958 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016959 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6960 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:026961 MockRead("HTTP/1.0 200 OK\r\n"),
6962 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6963 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066964 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026965 };
6966
[email protected]31a2bfe2010-02-09 08:03:396967 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6968 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076969 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026970
[email protected]8ddf8322012-02-23 18:08:066971 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076972 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:026973
[email protected]49639fa2011-12-20 23:22:416974 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026975
[email protected]49639fa2011-12-20 23:22:416976 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026977 EXPECT_EQ(ERR_IO_PENDING, rv);
6978
6979 rv = callback.WaitForResult();
6980 EXPECT_EQ(OK, rv);
6981
6982 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506983 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026984
[email protected]029c83b62013-01-24 05:28:206985 LoadTimingInfo load_timing_info;
6986 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6987 TestLoadTimingNotReusedWithPac(load_timing_info,
6988 CONNECT_TIMING_HAS_SSL_TIMES);
6989
[email protected]3cd17242009-06-23 02:59:026990 std::string response_text;
6991 rv = ReadTransaction(trans.get(), &response_text);
6992 EXPECT_EQ(OK, rv);
6993 EXPECT_EQ("Payload", response_text);
6994}
6995
[email protected]448d4ca52012-03-04 04:12:236996namespace {
6997
[email protected]04e5be32009-06-26 20:00:316998// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:066999
7000struct GroupNameTest {
7001 std::string proxy_server;
7002 std::string url;
7003 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187004 bool ssl;
[email protected]2d731a32010-04-29 01:04:067005};
7006
7007scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437008 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077009 SpdySessionDependencies* session_deps_) {
7010 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067011
[email protected]30d4c022013-07-18 22:58:167012 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537013 session->http_server_properties();
7014 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067015 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437016 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067017
7018 return session;
7019}
7020
7021int GroupNameTransactionHelper(
7022 const std::string& url,
7023 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067024 HttpRequestInfo request;
7025 request.method = "GET";
7026 request.url = GURL(url);
7027 request.load_flags = 0;
7028
[email protected]262eec82013-03-19 21:01:367029 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277031
[email protected]49639fa2011-12-20 23:22:417032 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067033
7034 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417035 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067036}
7037
[email protected]448d4ca52012-03-04 04:12:237038} // namespace
7039
[email protected]23e482282013-06-14 16:08:027040TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067041 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317042 {
[email protected]2d731a32010-04-29 01:04:067043 "", // unused
[email protected]04e5be32009-06-26 20:00:317044 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547045 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187046 false,
[email protected]2ff8b312010-04-26 22:20:547047 },
7048 {
[email protected]2d731a32010-04-29 01:04:067049 "", // unused
[email protected]2ff8b312010-04-26 22:20:547050 "http://[2001:1418:13:1::25]/direct",
7051 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187052 false,
[email protected]04e5be32009-06-26 20:00:317053 },
[email protected]04e5be32009-06-26 20:00:317054
7055 // SSL Tests
7056 {
[email protected]2d731a32010-04-29 01:04:067057 "", // unused
[email protected]04e5be32009-06-26 20:00:317058 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027059 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187060 true,
[email protected]04e5be32009-06-26 20:00:317061 },
7062 {
[email protected]2d731a32010-04-29 01:04:067063 "", // unused
7064 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027065 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187066 true,
[email protected]04e5be32009-06-26 20:00:317067 },
7068 {
[email protected]2d731a32010-04-29 01:04:067069 "", // unused
[email protected]2ff8b312010-04-26 22:20:547070 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027071 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187072 true,
[email protected]2ff8b312010-04-26 22:20:547073 },
[email protected]2d731a32010-04-29 01:04:067074 };
[email protected]2ff8b312010-04-26 22:20:547075
[email protected]8e6441ca2010-08-19 05:56:387076 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067077
7078 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077079 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027080 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067081 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437082 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067083
7084 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287085 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7086 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137087 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347088 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027089 MockClientSocketPoolManager* mock_pool_manager =
7090 new MockClientSocketPoolManager;
7091 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7092 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7093 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067094
7095 EXPECT_EQ(ERR_IO_PENDING,
7096 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187097 if (tests[i].ssl)
7098 EXPECT_EQ(tests[i].expected_group_name,
7099 ssl_conn_pool->last_group_name_received());
7100 else
7101 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287102 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067103 }
7104
[email protected]2d731a32010-04-29 01:04:067105}
7106
[email protected]23e482282013-06-14 16:08:027107TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067108 const GroupNameTest tests[] = {
7109 {
7110 "http_proxy",
7111 "http://www.google.com/http_proxy_normal",
7112 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187113 false,
[email protected]2d731a32010-04-29 01:04:067114 },
7115
7116 // SSL Tests
7117 {
7118 "http_proxy",
7119 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027120 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187121 true,
[email protected]2d731a32010-04-29 01:04:067122 },
[email protected]af3490e2010-10-16 21:02:297123
[email protected]9faeded92010-04-29 20:03:057124 {
7125 "http_proxy",
7126 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027127 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187128 true,
[email protected]9faeded92010-04-29 20:03:057129 },
[email protected]45499252013-01-23 17:12:567130
7131 {
7132 "http_proxy",
7133 "ftp://ftp.google.com/http_proxy_normal",
7134 "ftp/ftp.google.com:21",
7135 false,
7136 },
[email protected]2d731a32010-04-29 01:04:067137 };
7138
[email protected]8e6441ca2010-08-19 05:56:387139 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067140
7141 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077142 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027143 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067144 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437145 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067146
7147 HttpNetworkSessionPeer peer(session);
7148
[email protected]e60e47a2010-07-14 03:37:187149 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137150 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347151 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137152 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347153 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027154
7155 MockClientSocketPoolManager* mock_pool_manager =
7156 new MockClientSocketPoolManager;
7157 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7158 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7159 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067160
7161 EXPECT_EQ(ERR_IO_PENDING,
7162 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187163 if (tests[i].ssl)
7164 EXPECT_EQ(tests[i].expected_group_name,
7165 ssl_conn_pool->last_group_name_received());
7166 else
7167 EXPECT_EQ(tests[i].expected_group_name,
7168 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067169 }
[email protected]2d731a32010-04-29 01:04:067170}
7171
[email protected]23e482282013-06-14 16:08:027172TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067173 const GroupNameTest tests[] = {
7174 {
7175 "socks4://socks_proxy:1080",
7176 "http://www.google.com/socks4_direct",
7177 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187178 false,
[email protected]2d731a32010-04-29 01:04:067179 },
7180 {
7181 "socks5://socks_proxy:1080",
7182 "http://www.google.com/socks5_direct",
7183 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187184 false,
[email protected]2d731a32010-04-29 01:04:067185 },
7186
7187 // SSL Tests
7188 {
7189 "socks4://socks_proxy:1080",
7190 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027191 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187192 true,
[email protected]2d731a32010-04-29 01:04:067193 },
7194 {
7195 "socks5://socks_proxy:1080",
7196 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027197 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187198 true,
[email protected]2d731a32010-04-29 01:04:067199 },
[email protected]af3490e2010-10-16 21:02:297200
[email protected]9faeded92010-04-29 20:03:057201 {
7202 "socks4://socks_proxy:1080",
7203 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027204 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187205 true,
[email protected]9faeded92010-04-29 20:03:057206 },
[email protected]04e5be32009-06-26 20:00:317207 };
7208
[email protected]8e6441ca2010-08-19 05:56:387209 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547210
[email protected]04e5be32009-06-26 20:00:317211 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077212 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027213 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067214 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437215 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027216
[email protected]2d731a32010-04-29 01:04:067217 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317218
[email protected]e60e47a2010-07-14 03:37:187219 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137220 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347221 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137222 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347223 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027224
7225 MockClientSocketPoolManager* mock_pool_manager =
7226 new MockClientSocketPoolManager;
7227 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7228 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7229 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]04e5be32009-06-26 20:00:317230
[email protected]262eec82013-03-19 21:01:367231 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507232 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317233
[email protected]2d731a32010-04-29 01:04:067234 EXPECT_EQ(ERR_IO_PENDING,
7235 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187236 if (tests[i].ssl)
7237 EXPECT_EQ(tests[i].expected_group_name,
7238 ssl_conn_pool->last_group_name_received());
7239 else
7240 EXPECT_EQ(tests[i].expected_group_name,
7241 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317242 }
7243}
7244
[email protected]23e482282013-06-14 16:08:027245TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277246 HttpRequestInfo request;
7247 request.method = "GET";
7248 request.url = GURL("http://www.google.com/");
7249
[email protected]bb88e1d32013-05-03 23:11:077250 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007251 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327252
[email protected]69719062010-01-05 20:09:217253 // This simulates failure resolving all hostnames; that means we will fail
7254 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077255 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327256
[email protected]9172a982009-06-06 00:30:257257 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367258 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077259 CreateSession(&session_deps_)));
[email protected]9172a982009-06-06 00:30:257260
[email protected]49639fa2011-12-20 23:22:417261 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257262
[email protected]49639fa2011-12-20 23:22:417263 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257264 EXPECT_EQ(ERR_IO_PENDING, rv);
7265
[email protected]9172a982009-06-06 00:30:257266 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017267 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257268}
7269
[email protected]685af592010-05-11 19:31:247270// Base test to make sure that when the load flags for a request specify to
7271// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027272void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077273 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277274 // Issue a request, asking to bypass the cache(s).
7275 HttpRequestInfo request;
7276 request.method = "GET";
7277 request.load_flags = load_flags;
7278 request.url = GURL("http://www.google.com/");
7279
[email protected]a2c2fb92009-07-18 07:31:047280 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077281 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327282
[email protected]262eec82013-03-19 21:01:367283 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077284 CreateSession(&session_deps_)));
[email protected]3b9cca42009-06-16 01:08:287285
[email protected]6e78dfb2011-07-28 21:34:477286 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287287 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297288 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077289 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107290 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7291 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417292 &addrlist,
7293 callback.callback(),
7294 NULL,
7295 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477296 EXPECT_EQ(ERR_IO_PENDING, rv);
7297 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287298 EXPECT_EQ(OK, rv);
7299
7300 // Verify that it was added to host cache, by doing a subsequent async lookup
7301 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077302 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107303 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7304 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417305 &addrlist,
7306 callback.callback(),
7307 NULL,
7308 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327309 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287310
7311 // Inject a failure the next time that "www.google.com" is resolved. This way
7312 // we can tell if the next lookup hit the cache, or the "network".
7313 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077314 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287315
7316 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7317 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067318 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397319 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077320 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287321
[email protected]3b9cca42009-06-16 01:08:287322 // Run the request.
[email protected]49639fa2011-12-20 23:22:417323 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287324 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417325 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287326
7327 // If we bypassed the cache, we would have gotten a failure while resolving
7328 // "www.google.com".
7329 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7330}
7331
[email protected]685af592010-05-11 19:31:247332// There are multiple load flags that should trigger the host cache bypass.
7333// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027334TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247335 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7336}
7337
[email protected]23e482282013-06-14 16:08:027338TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247339 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7340}
7341
[email protected]23e482282013-06-14 16:08:027342TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247343 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7344}
7345
[email protected]0877e3d2009-10-17 22:29:577346// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027347TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]bb88e1d32013-05-03 23:11:077348 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577349
7350 HttpRequestInfo request;
7351 request.method = "GET";
7352 request.url = GURL("http://www.foo.com/");
7353 request.load_flags = 0;
7354
7355 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067356 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577357 };
[email protected]31a2bfe2010-02-09 08:03:397358 StaticSocketDataProvider data(NULL, 0,
7359 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077360 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577361
[email protected]49639fa2011-12-20 23:22:417362 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577363
7364 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367365 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077366 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577367
[email protected]49639fa2011-12-20 23:22:417368 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577369 EXPECT_EQ(ERR_IO_PENDING, rv);
7370
7371 rv = callback.WaitForResult();
7372 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7373}
7374
7375// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027376TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]bb88e1d32013-05-03 23:11:077377 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577378
7379 HttpRequestInfo request;
7380 request.method = "GET";
7381 request.url = GURL("http://www.foo.com/");
7382 request.load_flags = 0;
7383
7384 MockRead data_reads[] = {
7385 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067386 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577387 };
7388
[email protected]31a2bfe2010-02-09 08:03:397389 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077390 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577391
[email protected]49639fa2011-12-20 23:22:417392 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577393
7394 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367395 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077396 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577397
[email protected]49639fa2011-12-20 23:22:417398 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577399 EXPECT_EQ(ERR_IO_PENDING, rv);
7400
7401 rv = callback.WaitForResult();
7402 EXPECT_EQ(OK, rv);
7403
7404 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507405 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577406
[email protected]90499482013-06-01 00:39:507407 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577408 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7409
7410 std::string response_data;
7411 rv = ReadTransaction(trans.get(), &response_data);
7412 EXPECT_EQ(OK, rv);
7413 EXPECT_EQ("", response_data);
7414}
7415
7416// Make sure that a dropped connection while draining the body for auth
7417// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027418TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]bb88e1d32013-05-03 23:11:077419 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577420
7421 HttpRequestInfo request;
7422 request.method = "GET";
7423 request.url = GURL("http://www.google.com/");
7424 request.load_flags = 0;
7425
7426 MockWrite data_writes1[] = {
7427 MockWrite("GET / HTTP/1.1\r\n"
7428 "Host: www.google.com\r\n"
7429 "Connection: keep-alive\r\n\r\n"),
7430 };
7431
7432 MockRead data_reads1[] = {
7433 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7434 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7435 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7436 MockRead("Content-Length: 14\r\n\r\n"),
7437 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067438 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577439 };
7440
[email protected]31a2bfe2010-02-09 08:03:397441 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7442 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077443 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577444
7445 // After calling trans->RestartWithAuth(), this is the request we should
7446 // be issuing -- the final header line contains the credentials.
7447 MockWrite data_writes2[] = {
7448 MockWrite("GET / HTTP/1.1\r\n"
7449 "Host: www.google.com\r\n"
7450 "Connection: keep-alive\r\n"
7451 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7452 };
7453
7454 // Lastly, the server responds with the actual content.
7455 MockRead data_reads2[] = {
7456 MockRead("HTTP/1.1 200 OK\r\n"),
7457 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7458 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067459 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577460 };
7461
[email protected]31a2bfe2010-02-09 08:03:397462 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7463 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077464 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]0877e3d2009-10-17 22:29:577465
[email protected]49639fa2011-12-20 23:22:417466 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577467
[email protected]262eec82013-03-19 21:01:367468 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507469 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507470
[email protected]49639fa2011-12-20 23:22:417471 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577472 EXPECT_EQ(ERR_IO_PENDING, rv);
7473
7474 rv = callback1.WaitForResult();
7475 EXPECT_EQ(OK, rv);
7476
7477 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507478 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047479 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577480
[email protected]49639fa2011-12-20 23:22:417481 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577482
[email protected]49639fa2011-12-20 23:22:417483 rv = trans->RestartWithAuth(
7484 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577485 EXPECT_EQ(ERR_IO_PENDING, rv);
7486
7487 rv = callback2.WaitForResult();
7488 EXPECT_EQ(OK, rv);
7489
7490 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507491 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577492 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7493 EXPECT_EQ(100, response->headers->GetContentLength());
7494}
7495
7496// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027497TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077498 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577499
7500 HttpRequestInfo request;
7501 request.method = "GET";
7502 request.url = GURL("https://www.google.com/");
7503 request.load_flags = 0;
7504
7505 MockRead proxy_reads[] = {
7506 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067507 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577508 };
7509
[email protected]31a2bfe2010-02-09 08:03:397510 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067511 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577512
[email protected]bb88e1d32013-05-03 23:11:077513 session_deps_.socket_factory->AddSocketDataProvider(&data);
7514 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577515
[email protected]49639fa2011-12-20 23:22:417516 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577517
[email protected]bb88e1d32013-05-03 23:11:077518 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577519
7520 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367521 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077522 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577523
[email protected]49639fa2011-12-20 23:22:417524 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577525 EXPECT_EQ(ERR_IO_PENDING, rv);
7526
7527 rv = callback.WaitForResult();
7528 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7529}
7530
[email protected]23e482282013-06-14 16:08:027531TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467532 HttpRequestInfo request;
7533 request.method = "GET";
7534 request.url = GURL("http://www.google.com/");
7535 request.load_flags = 0;
7536
[email protected]cb9bf6ca2011-01-28 13:15:277537 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367538 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077539 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:277540
[email protected]e22e1362009-11-23 21:31:127541 MockRead data_reads[] = {
7542 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067543 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127544 };
[email protected]9492e4a2010-02-24 00:58:467545
7546 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077547 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467548
[email protected]49639fa2011-12-20 23:22:417549 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467550
[email protected]49639fa2011-12-20 23:22:417551 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467552 EXPECT_EQ(ERR_IO_PENDING, rv);
7553
7554 EXPECT_EQ(OK, callback.WaitForResult());
7555
7556 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507557 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467558
[email protected]90499482013-06-01 00:39:507559 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467560 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7561
7562 std::string response_data;
7563 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237564 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127565}
7566
[email protected]23e482282013-06-14 16:08:027567TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157568 base::FilePath temp_file_path;
[email protected]95d88ffe2010-02-04 21:25:337569 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
7570 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217571 UploadFileElementReader::ScopedOverridingContentLengthForTests
7572 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337573
[email protected]b2d26cfd2012-12-11 10:36:067574 ScopedVector<UploadElementReader> element_readers;
7575 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367576 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7577 temp_file_path,
7578 0,
7579 kuint64max,
7580 base::Time()));
[email protected]96c77a72013-09-24 09:49:207581 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277582
7583 HttpRequestInfo request;
7584 request.method = "POST";
7585 request.url = GURL("http://www.google.com/upload");
7586 request.upload_data_stream = &upload_data_stream;
7587 request.load_flags = 0;
7588
[email protected]329b68b2012-11-14 17:54:277589 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367590 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077591 CreateSession(&session_deps_)));
[email protected]95d88ffe2010-02-04 21:25:337592
7593 MockRead data_reads[] = {
7594 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7595 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067596 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337597 };
[email protected]31a2bfe2010-02-09 08:03:397598 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077599 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337600
[email protected]49639fa2011-12-20 23:22:417601 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337602
[email protected]49639fa2011-12-20 23:22:417603 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337604 EXPECT_EQ(ERR_IO_PENDING, rv);
7605
7606 rv = callback.WaitForResult();
7607 EXPECT_EQ(OK, rv);
7608
7609 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507610 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337611
[email protected]90499482013-06-01 00:39:507612 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337613 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7614
7615 std::string response_data;
7616 rv = ReadTransaction(trans.get(), &response_data);
7617 EXPECT_EQ(OK, rv);
7618 EXPECT_EQ("hello world", response_data);
7619
[email protected]dd3aa792013-07-16 19:10:237620 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:337621}
7622
[email protected]23e482282013-06-14 16:08:027623TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157624 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367625 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7626 std::string temp_file_content("Unreadable file.");
7627 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
7628 temp_file_content.length()));
7629 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7630
[email protected]b2d26cfd2012-12-11 10:36:067631 ScopedVector<UploadElementReader> element_readers;
7632 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367633 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7634 temp_file,
7635 0,
7636 kuint64max,
7637 base::Time()));
[email protected]96c77a72013-09-24 09:49:207638 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277639
7640 HttpRequestInfo request;
7641 request.method = "POST";
7642 request.url = GURL("http://www.google.com/upload");
7643 request.upload_data_stream = &upload_data_stream;
7644 request.load_flags = 0;
7645
7646 // If we try to upload an unreadable file, the network stack should report
7647 // the file size as zero and upload zero bytes for that file.
[email protected]329b68b2012-11-14 17:54:277648 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367649 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077650 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367651
7652 MockRead data_reads[] = {
7653 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067654 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367655 };
7656 MockWrite data_writes[] = {
7657 MockWrite("POST /upload HTTP/1.1\r\n"
7658 "Host: www.google.com\r\n"
7659 "Connection: keep-alive\r\n"
7660 "Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067661 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367662 };
7663 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7664 arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077665 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367666
[email protected]49639fa2011-12-20 23:22:417667 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:367668
[email protected]49639fa2011-12-20 23:22:417669 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367670 EXPECT_EQ(ERR_IO_PENDING, rv);
7671
7672 rv = callback.WaitForResult();
7673 EXPECT_EQ(OK, rv);
7674
7675 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507676 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507677 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367678 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7679
[email protected]dd3aa792013-07-16 19:10:237680 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367681}
7682
[email protected]23e482282013-06-14 16:08:027683TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
[email protected]6cdfd7f2013-02-08 20:40:157684 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367685 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7686 std::string temp_file_contents("Unreadable file.");
7687 std::string unreadable_contents(temp_file_contents.length(), '\0');
7688 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
7689 temp_file_contents.length()));
7690
[email protected]b2d26cfd2012-12-11 10:36:067691 ScopedVector<UploadElementReader> element_readers;
7692 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367693 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7694 temp_file,
7695 0,
7696 kuint64max,
7697 base::Time()));
[email protected]96c77a72013-09-24 09:49:207698 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277699
7700 HttpRequestInfo request;
7701 request.method = "POST";
7702 request.url = GURL("http://www.google.com/upload");
7703 request.upload_data_stream = &upload_data_stream;
7704 request.load_flags = 0;
7705
[email protected]329b68b2012-11-14 17:54:277706 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367707 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077708 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367709
7710 MockRead data_reads[] = {
7711 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7712 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7713 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
7714
7715 MockRead("HTTP/1.1 200 OK\r\n"),
7716 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067717 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367718 };
7719 MockWrite data_writes[] = {
7720 MockWrite("POST /upload HTTP/1.1\r\n"
7721 "Host: www.google.com\r\n"
7722 "Connection: keep-alive\r\n"
7723 "Content-Length: 16\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067724 MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
[email protected]6624b4622010-03-29 19:58:367725
7726 MockWrite("POST /upload HTTP/1.1\r\n"
7727 "Host: www.google.com\r\n"
7728 "Connection: keep-alive\r\n"
[email protected]d98961652012-09-11 20:27:217729 "Content-Length: 0\r\n"
[email protected]6624b4622010-03-29 19:58:367730 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067731 MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
7732 temp_file_contents.length()),
7733 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367734 };
7735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7736 arraysize(data_writes));
[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 callback1;
[email protected]6624b4622010-03-29 19:58:367740
[email protected]49639fa2011-12-20 23:22:417741 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367742 EXPECT_EQ(ERR_IO_PENDING, rv);
7743
7744 rv = callback1.WaitForResult();
7745 EXPECT_EQ(OK, rv);
7746
7747 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:047748 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507749 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367750 EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
[email protected]79cb5c12011-09-12 13:12:047751 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]6624b4622010-03-29 19:58:367752
7753 // Now make the file unreadable and try again.
7754 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7755
[email protected]49639fa2011-12-20 23:22:417756 TestCompletionCallback callback2;
[email protected]6624b4622010-03-29 19:58:367757
[email protected]49639fa2011-12-20 23:22:417758 rv = trans->RestartWithAuth(
7759 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]6624b4622010-03-29 19:58:367760 EXPECT_EQ(ERR_IO_PENDING, rv);
7761
7762 rv = callback2.WaitForResult();
7763 EXPECT_EQ(OK, rv);
7764
7765 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507766 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507767 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367768 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7769 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7770
[email protected]dd3aa792013-07-16 19:10:237771 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367772}
7773
[email protected]02cad5d2013-10-02 08:14:037774TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
7775 class FakeUploadElementReader : public UploadElementReader {
7776 public:
7777 FakeUploadElementReader() {}
7778 virtual ~FakeUploadElementReader() {}
7779
7780 const CompletionCallback& callback() const { return callback_; }
7781
7782 // UploadElementReader overrides:
7783 virtual int Init(const CompletionCallback& callback) OVERRIDE {
7784 callback_ = callback;
7785 return ERR_IO_PENDING;
7786 }
7787 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
7788 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
7789 virtual int Read(IOBuffer* buf,
7790 int buf_length,
7791 const CompletionCallback& callback) OVERRIDE {
7792 return ERR_FAILED;
7793 }
7794
7795 private:
7796 CompletionCallback callback_;
7797 };
7798
7799 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
7800 ScopedVector<UploadElementReader> element_readers;
7801 element_readers.push_back(fake_reader);
7802 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7803
7804 HttpRequestInfo request;
7805 request.method = "POST";
7806 request.url = GURL("http://www.google.com/upload");
7807 request.upload_data_stream = &upload_data_stream;
7808 request.load_flags = 0;
7809
7810 scoped_ptr<HttpTransaction> trans(
7811 new HttpNetworkTransaction(DEFAULT_PRIORITY,
7812 CreateSession(&session_deps_)));
7813
7814 StaticSocketDataProvider data;
7815 session_deps_.socket_factory->AddSocketDataProvider(&data);
7816
7817 TestCompletionCallback callback;
7818 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7819 EXPECT_EQ(ERR_IO_PENDING, rv);
7820 base::MessageLoop::current()->RunUntilIdle();
7821
7822 // Transaction is pending on request body initialization.
7823 ASSERT_FALSE(fake_reader->callback().is_null());
7824
7825 // Return Init()'s result after the transaction gets destroyed.
7826 trans.reset();
7827 fake_reader->callback().Run(OK); // Should not crash.
7828}
7829
[email protected]aeefc9e82010-02-19 16:18:277830// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:027831TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:277832
7833 HttpRequestInfo request;
7834 request.method = "GET";
7835 request.url = GURL("http://www.google.com/");
7836 request.load_flags = 0;
7837
7838 // First transaction will request a resource and receive a Basic challenge
7839 // with realm="first_realm".
7840 MockWrite data_writes1[] = {
7841 MockWrite("GET / HTTP/1.1\r\n"
7842 "Host: www.google.com\r\n"
7843 "Connection: keep-alive\r\n"
7844 "\r\n"),
7845 };
7846 MockRead data_reads1[] = {
7847 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7848 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7849 "\r\n"),
7850 };
7851
7852 // After calling trans->RestartWithAuth(), provide an Authentication header
7853 // for first_realm. The server will reject and provide a challenge with
7854 // second_realm.
7855 MockWrite data_writes2[] = {
7856 MockWrite("GET / HTTP/1.1\r\n"
7857 "Host: www.google.com\r\n"
7858 "Connection: keep-alive\r\n"
7859 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7860 "\r\n"),
7861 };
7862 MockRead data_reads2[] = {
7863 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7864 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7865 "\r\n"),
7866 };
7867
7868 // This again fails, and goes back to first_realm. Make sure that the
7869 // entry is removed from cache.
7870 MockWrite data_writes3[] = {
7871 MockWrite("GET / HTTP/1.1\r\n"
7872 "Host: www.google.com\r\n"
7873 "Connection: keep-alive\r\n"
7874 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
7875 "\r\n"),
7876 };
7877 MockRead data_reads3[] = {
7878 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7879 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7880 "\r\n"),
7881 };
7882
7883 // Try one last time (with the correct password) and get the resource.
7884 MockWrite data_writes4[] = {
7885 MockWrite("GET / HTTP/1.1\r\n"
7886 "Host: www.google.com\r\n"
7887 "Connection: keep-alive\r\n"
7888 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
7889 "\r\n"),
7890 };
7891 MockRead data_reads4[] = {
7892 MockRead("HTTP/1.1 200 OK\r\n"
7893 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:507894 "Content-Length: 5\r\n"
7895 "\r\n"
7896 "hello"),
[email protected]aeefc9e82010-02-19 16:18:277897 };
7898
7899 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7900 data_writes1, arraysize(data_writes1));
7901 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7902 data_writes2, arraysize(data_writes2));
7903 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7904 data_writes3, arraysize(data_writes3));
7905 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
7906 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:077907 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7908 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7909 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7910 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:277911
[email protected]49639fa2011-12-20 23:22:417912 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:277913
[email protected]0b0bf032010-09-21 18:08:507914 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367915 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077916 CreateSession(&session_deps_)));
[email protected]0b0bf032010-09-21 18:08:507917
[email protected]aeefc9e82010-02-19 16:18:277918 // Issue the first request with Authorize headers. There should be a
7919 // password prompt for first_realm waiting to be filled in after the
7920 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417921 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:277922 EXPECT_EQ(ERR_IO_PENDING, rv);
7923 rv = callback1.WaitForResult();
7924 EXPECT_EQ(OK, rv);
7925 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507926 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047927 const AuthChallengeInfo* challenge = response->auth_challenge.get();
7928 ASSERT_FALSE(challenge == NULL);
7929 EXPECT_FALSE(challenge->is_proxy);
7930 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7931 EXPECT_EQ("first_realm", challenge->realm);
7932 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277933
7934 // Issue the second request with an incorrect password. There should be a
7935 // password prompt for second_realm waiting to be filled in after the
7936 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417937 TestCompletionCallback callback2;
7938 rv = trans->RestartWithAuth(
7939 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:277940 EXPECT_EQ(ERR_IO_PENDING, rv);
7941 rv = callback2.WaitForResult();
7942 EXPECT_EQ(OK, rv);
7943 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507944 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047945 challenge = response->auth_challenge.get();
7946 ASSERT_FALSE(challenge == NULL);
7947 EXPECT_FALSE(challenge->is_proxy);
7948 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7949 EXPECT_EQ("second_realm", challenge->realm);
7950 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277951
7952 // Issue the third request with another incorrect password. There should be
7953 // a password prompt for first_realm waiting to be filled in. If the password
7954 // prompt is not present, it indicates that the HttpAuthCacheEntry for
7955 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:417956 TestCompletionCallback callback3;
7957 rv = trans->RestartWithAuth(
7958 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:277959 EXPECT_EQ(ERR_IO_PENDING, rv);
7960 rv = callback3.WaitForResult();
7961 EXPECT_EQ(OK, rv);
7962 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507963 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047964 challenge = response->auth_challenge.get();
7965 ASSERT_FALSE(challenge == NULL);
7966 EXPECT_FALSE(challenge->is_proxy);
7967 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7968 EXPECT_EQ("first_realm", challenge->realm);
7969 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277970
7971 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:417972 TestCompletionCallback callback4;
7973 rv = trans->RestartWithAuth(
7974 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:277975 EXPECT_EQ(ERR_IO_PENDING, rv);
7976 rv = callback4.WaitForResult();
7977 EXPECT_EQ(OK, rv);
7978 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507979 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:277980 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7981}
7982
[email protected]23e482282013-06-14 16:08:027983TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:037984 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:237985 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:427986
[email protected]8a0fc822013-06-27 20:52:437987 std::string alternate_protocol_http_header =
7988 GetAlternateProtocolHttpHeader();
7989
[email protected]564b4912010-03-09 16:30:427990 MockRead data_reads[] = {
7991 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:437992 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:427993 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067994 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:427995 };
7996
7997 HttpRequestInfo request;
7998 request.method = "GET";
7999 request.url = GURL("http://www.google.com/");
8000 request.load_flags = 0;
8001
8002 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8003
[email protected]bb88e1d32013-05-03 23:11:078004 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428005
[email protected]49639fa2011-12-20 23:22:418006 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428007
[email protected]bb88e1d32013-05-03 23:11:078008 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368009 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508010 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428011
[email protected]49639fa2011-12-20 23:22:418012 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428013 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538014
[email protected]2fbaecf22010-07-22 22:20:358015 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]17291a022011-10-10 07:32:538016 const HttpServerProperties& http_server_properties =
8017 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428018 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538019 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428020
8021 EXPECT_EQ(OK, callback.WaitForResult());
8022
8023 const HttpResponseInfo* response = trans->GetResponseInfo();
8024 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508025 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428026 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538027 EXPECT_FALSE(response->was_fetched_via_spdy);
8028 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428029
8030 std::string response_data;
8031 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8032 EXPECT_EQ("hello world", response_data);
8033
[email protected]17291a022011-10-10 07:32:538034 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8035 const PortAlternateProtocolPair alternate =
8036 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8037 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428038 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438039 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428040 EXPECT_TRUE(expected_alternate.Equals(alternate));
8041}
8042
[email protected]23e482282013-06-14 16:08:028043TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238044 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388045 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428046
8047 HttpRequestInfo request;
8048 request.method = "GET";
8049 request.url = GURL("http://www.google.com/");
8050 request.load_flags = 0;
8051
[email protected]d973e99a2012-02-17 21:02:368052 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428053 StaticSocketDataProvider first_data;
8054 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078055 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428056
8057 MockRead data_reads[] = {
8058 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8059 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068060 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428061 };
8062 StaticSocketDataProvider second_data(
8063 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078064 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428065
[email protected]bb88e1d32013-05-03 23:11:078066 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428067
[email protected]30d4c022013-07-18 22:58:168068 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538069 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118070 // Port must be < 1024, or the header will be ignored (since initial port was
8071 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538072 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118073 HostPortPair::FromURL(request.url),
8074 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438075 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428076
[email protected]262eec82013-03-19 21:01:368077 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418079 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428080
[email protected]49639fa2011-12-20 23:22:418081 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428082 EXPECT_EQ(ERR_IO_PENDING, rv);
8083 EXPECT_EQ(OK, callback.WaitForResult());
8084
8085 const HttpResponseInfo* response = trans->GetResponseInfo();
8086 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508087 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428088 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8089
8090 std::string response_data;
8091 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8092 EXPECT_EQ("hello world", response_data);
8093
[email protected]17291a022011-10-10 07:32:538094 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118095 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538096 const PortAlternateProtocolPair alternate =
8097 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118098 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538099 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428100}
8101
[email protected]23e482282013-06-14 16:08:028102TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238103 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118104 // Ensure that we're not allowed to redirect traffic via an alternate
8105 // protocol to an unrestricted (port >= 1024) when the original traffic was
8106 // on a restricted port (port < 1024). Ensure that we can redirect in all
8107 // other cases.
8108 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118109
8110 HttpRequestInfo restricted_port_request;
8111 restricted_port_request.method = "GET";
8112 restricted_port_request.url = GURL("http://www.google.com:1023/");
8113 restricted_port_request.load_flags = 0;
8114
[email protected]d973e99a2012-02-17 21:02:368115 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118116 StaticSocketDataProvider first_data;
8117 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078118 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118119
8120 MockRead data_reads[] = {
8121 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8122 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068123 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118124 };
8125 StaticSocketDataProvider second_data(
8126 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078127 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118128
[email protected]bb88e1d32013-05-03 23:11:078129 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118130
[email protected]30d4c022013-07-18 22:58:168131 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538132 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118133 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538134 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118135 HostPortPair::FromURL(restricted_port_request.url),
8136 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438137 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118138
[email protected]262eec82013-03-19 21:01:368139 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508140 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418141 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118142
[email protected]49639fa2011-12-20 23:22:418143 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368144 &restricted_port_request,
8145 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118146 EXPECT_EQ(ERR_IO_PENDING, rv);
8147 // Invalid change to unrestricted port should fail.
8148 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198149}
[email protected]3912662a32011-10-04 00:51:118150
[email protected]23e482282013-06-14 16:08:028151TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198152 AlternateProtocolPortRestrictedPermitted) {
8153 // Ensure that we're allowed to redirect traffic via an alternate
8154 // protocol to an unrestricted (port >= 1024) when the original traffic was
8155 // on a restricted port (port < 1024) if we set
8156 // enable_user_alternate_protocol_ports.
8157
8158 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078159 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198160
8161 HttpRequestInfo restricted_port_request;
8162 restricted_port_request.method = "GET";
8163 restricted_port_request.url = GURL("http://www.google.com:1023/");
8164 restricted_port_request.load_flags = 0;
8165
8166 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8167 StaticSocketDataProvider first_data;
8168 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078169 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198170
8171 MockRead data_reads[] = {
8172 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8173 MockRead("hello world"),
8174 MockRead(ASYNC, OK),
8175 };
8176 StaticSocketDataProvider second_data(
8177 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078178 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198179
[email protected]bb88e1d32013-05-03 23:11:078180 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198181
[email protected]30d4c022013-07-18 22:58:168182 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198183 session->http_server_properties();
8184 const int kUnrestrictedAlternatePort = 1024;
8185 http_server_properties->SetAlternateProtocol(
8186 HostPortPair::FromURL(restricted_port_request.url),
8187 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438188 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198189
[email protected]262eec82013-03-19 21:01:368190 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198192 TestCompletionCallback callback;
8193
8194 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368195 &restricted_port_request,
8196 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198197 // Change to unrestricted port should succeed.
8198 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118199}
8200
[email protected]23e482282013-06-14 16:08:028201TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238202 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118203 // Ensure that we're not allowed to redirect traffic via an alternate
8204 // protocol to an unrestricted (port >= 1024) when the original traffic was
8205 // on a restricted port (port < 1024). Ensure that we can redirect in all
8206 // other cases.
8207 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118208
8209 HttpRequestInfo restricted_port_request;
8210 restricted_port_request.method = "GET";
8211 restricted_port_request.url = GURL("http://www.google.com:1023/");
8212 restricted_port_request.load_flags = 0;
8213
[email protected]d973e99a2012-02-17 21:02:368214 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118215 StaticSocketDataProvider first_data;
8216 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078217 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118218
8219 MockRead data_reads[] = {
8220 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8221 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068222 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118223 };
8224 StaticSocketDataProvider second_data(
8225 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078226 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118227
[email protected]bb88e1d32013-05-03 23:11:078228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118229
[email protected]30d4c022013-07-18 22:58:168230 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538231 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118232 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538233 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118234 HostPortPair::FromURL(restricted_port_request.url),
8235 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438236 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118237
[email protected]262eec82013-03-19 21:01:368238 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418240 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118241
[email protected]49639fa2011-12-20 23:22:418242 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368243 &restricted_port_request,
8244 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118245 EXPECT_EQ(ERR_IO_PENDING, rv);
8246 // Valid change to restricted port should pass.
8247 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118248}
8249
[email protected]23e482282013-06-14 16:08:028250TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238251 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118252 // Ensure that we're not allowed to redirect traffic via an alternate
8253 // protocol to an unrestricted (port >= 1024) when the original traffic was
8254 // on a restricted port (port < 1024). Ensure that we can redirect in all
8255 // other cases.
8256 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118257
8258 HttpRequestInfo unrestricted_port_request;
8259 unrestricted_port_request.method = "GET";
8260 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8261 unrestricted_port_request.load_flags = 0;
8262
[email protected]d973e99a2012-02-17 21:02:368263 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118264 StaticSocketDataProvider first_data;
8265 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078266 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118267
8268 MockRead data_reads[] = {
8269 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8270 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068271 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118272 };
8273 StaticSocketDataProvider second_data(
8274 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078275 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118276
[email protected]bb88e1d32013-05-03 23:11:078277 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118278
[email protected]30d4c022013-07-18 22:58:168279 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538280 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118281 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538282 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118283 HostPortPair::FromURL(unrestricted_port_request.url),
8284 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438285 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118286
[email protected]262eec82013-03-19 21:01:368287 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508288 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418289 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118290
[email protected]49639fa2011-12-20 23:22:418291 int rv = trans->Start(
8292 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118293 EXPECT_EQ(ERR_IO_PENDING, rv);
8294 // Valid change to restricted port should pass.
8295 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118296}
8297
[email protected]23e482282013-06-14 16:08:028298TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238299 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118300 // Ensure that we're not allowed to redirect traffic via an alternate
8301 // protocol to an unrestricted (port >= 1024) when the original traffic was
8302 // on a restricted port (port < 1024). Ensure that we can redirect in all
8303 // other cases.
8304 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118305
8306 HttpRequestInfo unrestricted_port_request;
8307 unrestricted_port_request.method = "GET";
8308 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8309 unrestricted_port_request.load_flags = 0;
8310
[email protected]d973e99a2012-02-17 21:02:368311 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118312 StaticSocketDataProvider first_data;
8313 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078314 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118315
8316 MockRead data_reads[] = {
8317 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8318 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068319 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118320 };
8321 StaticSocketDataProvider second_data(
8322 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078323 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118324
[email protected]bb88e1d32013-05-03 23:11:078325 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118326
[email protected]30d4c022013-07-18 22:58:168327 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538328 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118329 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538330 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118331 HostPortPair::FromURL(unrestricted_port_request.url),
8332 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438333 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118334
[email protected]262eec82013-03-19 21:01:368335 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508336 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418337 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118338
[email protected]49639fa2011-12-20 23:22:418339 int rv = trans->Start(
8340 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118341 EXPECT_EQ(ERR_IO_PENDING, rv);
8342 // Valid change to an unrestricted port should pass.
8343 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118344}
8345
[email protected]23e482282013-06-14 16:08:028346TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238347 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028348 // Ensure that we're not allowed to redirect traffic via an alternate
8349 // protocol to an unsafe port, and that we resume the second
8350 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8351 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028352
8353 HttpRequestInfo request;
8354 request.method = "GET";
8355 request.url = GURL("http://www.google.com/");
8356 request.load_flags = 0;
8357
8358 // The alternate protocol request will error out before we attempt to connect,
8359 // so only the standard HTTP request will try to connect.
8360 MockRead data_reads[] = {
8361 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8362 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068363 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028364 };
8365 StaticSocketDataProvider data(
8366 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078367 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028368
[email protected]bb88e1d32013-05-03 23:11:078369 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028370
[email protected]30d4c022013-07-18 22:58:168371 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028372 session->http_server_properties();
8373 const int kUnsafePort = 7;
8374 http_server_properties->SetAlternateProtocol(
8375 HostPortPair::FromURL(request.url),
8376 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438377 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028378
[email protected]262eec82013-03-19 21:01:368379 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028381 TestCompletionCallback callback;
8382
8383 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8384 EXPECT_EQ(ERR_IO_PENDING, rv);
8385 // The HTTP request should succeed.
8386 EXPECT_EQ(OK, callback.WaitForResult());
8387
8388 // Disable alternate protocol before the asserts.
8389 HttpStreamFactory::set_use_alternate_protocols(false);
8390
8391 const HttpResponseInfo* response = trans->GetResponseInfo();
8392 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508393 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028394 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8395
8396 std::string response_data;
8397 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8398 EXPECT_EQ("hello world", response_data);
8399}
8400
[email protected]23e482282013-06-14 16:08:028401TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388402 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038403 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548404
8405 HttpRequestInfo request;
8406 request.method = "GET";
8407 request.url = GURL("http://www.google.com/");
8408 request.load_flags = 0;
8409
[email protected]8a0fc822013-06-27 20:52:438410 std::string alternate_protocol_http_header =
8411 GetAlternateProtocolHttpHeader();
8412
[email protected]2ff8b312010-04-26 22:20:548413 MockRead data_reads[] = {
8414 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438415 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548416 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178417 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8418 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548419 };
8420
8421 StaticSocketDataProvider first_transaction(
8422 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078423 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548424
[email protected]8ddf8322012-02-23 18:08:068425 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028426 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548428
[email protected]cdf8f7e72013-05-23 10:56:468429 scoped_ptr<SpdyFrame> req(
8430 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138431 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548432
[email protected]23e482282013-06-14 16:08:028433 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8434 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548435 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138436 CreateMockRead(*resp),
8437 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068438 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548439 };
8440
[email protected]dd54bd82012-07-19 23:44:578441 DelayedSocketData spdy_data(
8442 1, // wait for one write to finish before reading.
8443 spdy_reads, arraysize(spdy_reads),
8444 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078445 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548446
[email protected]d973e99a2012-02-17 21:02:368447 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558448 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8449 NULL, 0, NULL, 0);
8450 hanging_non_alternate_protocol_socket.set_connect_data(
8451 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078452 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558453 &hanging_non_alternate_protocol_socket);
8454
[email protected]49639fa2011-12-20 23:22:418455 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548456
[email protected]bb88e1d32013-05-03 23:11:078457 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368458 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548460
[email protected]49639fa2011-12-20 23:22:418461 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548462 EXPECT_EQ(ERR_IO_PENDING, rv);
8463 EXPECT_EQ(OK, callback.WaitForResult());
8464
8465 const HttpResponseInfo* response = trans->GetResponseInfo();
8466 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508467 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548468 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8469
8470 std::string response_data;
8471 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8472 EXPECT_EQ("hello world", response_data);
8473
[email protected]90499482013-06-01 00:39:508474 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548475
[email protected]49639fa2011-12-20 23:22:418476 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548477 EXPECT_EQ(ERR_IO_PENDING, rv);
8478 EXPECT_EQ(OK, callback.WaitForResult());
8479
8480 response = trans->GetResponseInfo();
8481 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508482 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548483 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538484 EXPECT_TRUE(response->was_fetched_via_spdy);
8485 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548486
8487 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8488 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548489}
8490
[email protected]23e482282013-06-14 16:08:028491TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558492 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038493 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558494
8495 HttpRequestInfo request;
8496 request.method = "GET";
8497 request.url = GURL("http://www.google.com/");
8498 request.load_flags = 0;
8499
[email protected]8a0fc822013-06-27 20:52:438500 std::string alternate_protocol_http_header =
8501 GetAlternateProtocolHttpHeader();
8502
[email protected]2d6728692011-03-12 01:39:558503 MockRead data_reads[] = {
8504 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438505 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558506 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178507 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068508 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558509 };
8510
8511 StaticSocketDataProvider first_transaction(
8512 data_reads, arraysize(data_reads), NULL, 0);
8513 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078514 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558515
[email protected]d973e99a2012-02-17 21:02:368516 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558517 StaticSocketDataProvider hanging_socket(
8518 NULL, 0, NULL, 0);
8519 hanging_socket.set_connect_data(never_finishing_connect);
8520 // Socket 2 and 3 are the hanging Alternate-Protocol and
8521 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078522 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8523 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558524
[email protected]8ddf8322012-02-23 18:08:068525 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028526 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078527 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558528
[email protected]cdf8f7e72013-05-23 10:56:468529 scoped_ptr<SpdyFrame> req1(
8530 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8531 scoped_ptr<SpdyFrame> req2(
8532 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558533 MockWrite spdy_writes[] = {
8534 CreateMockWrite(*req1),
8535 CreateMockWrite(*req2),
8536 };
[email protected]23e482282013-06-14 16:08:028537 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8538 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8539 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8540 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558541 MockRead spdy_reads[] = {
8542 CreateMockRead(*resp1),
8543 CreateMockRead(*data1),
8544 CreateMockRead(*resp2),
8545 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068546 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558547 };
8548
[email protected]dd54bd82012-07-19 23:44:578549 DelayedSocketData spdy_data(
8550 2, // wait for writes to finish before reading.
8551 spdy_reads, arraysize(spdy_reads),
8552 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558553 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078554 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558555
8556 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078557 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558558
[email protected]bb88e1d32013-05-03 23:11:078559 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418560 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508561 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558562
[email protected]49639fa2011-12-20 23:22:418563 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558564 EXPECT_EQ(ERR_IO_PENDING, rv);
8565 EXPECT_EQ(OK, callback1.WaitForResult());
8566
8567 const HttpResponseInfo* response = trans1.GetResponseInfo();
8568 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508569 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558570 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8571
8572 std::string response_data;
8573 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8574 EXPECT_EQ("hello world", response_data);
8575
[email protected]49639fa2011-12-20 23:22:418576 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508577 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418578 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558579 EXPECT_EQ(ERR_IO_PENDING, rv);
8580
[email protected]49639fa2011-12-20 23:22:418581 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508582 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418583 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558584 EXPECT_EQ(ERR_IO_PENDING, rv);
8585
8586 EXPECT_EQ(OK, callback2.WaitForResult());
8587 EXPECT_EQ(OK, callback3.WaitForResult());
8588
8589 response = trans2.GetResponseInfo();
8590 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508591 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558592 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8593 EXPECT_TRUE(response->was_fetched_via_spdy);
8594 EXPECT_TRUE(response->was_npn_negotiated);
8595 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8596 EXPECT_EQ("hello!", response_data);
8597
8598 response = trans3.GetResponseInfo();
8599 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508600 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8602 EXPECT_TRUE(response->was_fetched_via_spdy);
8603 EXPECT_TRUE(response->was_npn_negotiated);
8604 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8605 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558606}
8607
[email protected]23e482282013-06-14 16:08:028608TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558609 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038610 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558611
8612 HttpRequestInfo request;
8613 request.method = "GET";
8614 request.url = GURL("http://www.google.com/");
8615 request.load_flags = 0;
8616
[email protected]8a0fc822013-06-27 20:52:438617 std::string alternate_protocol_http_header =
8618 GetAlternateProtocolHttpHeader();
8619
[email protected]2d6728692011-03-12 01:39:558620 MockRead data_reads[] = {
8621 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438622 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558623 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178624 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068625 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558626 };
8627
8628 StaticSocketDataProvider first_transaction(
8629 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078630 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558631
[email protected]8ddf8322012-02-23 18:08:068632 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028633 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558635
[email protected]d973e99a2012-02-17 21:02:368636 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558637 StaticSocketDataProvider hanging_alternate_protocol_socket(
8638 NULL, 0, NULL, 0);
8639 hanging_alternate_protocol_socket.set_connect_data(
8640 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078641 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558642 &hanging_alternate_protocol_socket);
8643
8644 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078645 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558646
[email protected]49639fa2011-12-20 23:22:418647 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558648
[email protected]bb88e1d32013-05-03 23:11:078649 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368650 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508651 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558652
[email protected]49639fa2011-12-20 23:22:418653 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558654 EXPECT_EQ(ERR_IO_PENDING, rv);
8655 EXPECT_EQ(OK, callback.WaitForResult());
8656
8657 const HttpResponseInfo* response = trans->GetResponseInfo();
8658 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508659 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558660 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8661
8662 std::string response_data;
8663 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8664 EXPECT_EQ("hello world", response_data);
8665
[email protected]90499482013-06-01 00:39:508666 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558667
[email protected]49639fa2011-12-20 23:22:418668 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558669 EXPECT_EQ(ERR_IO_PENDING, rv);
8670 EXPECT_EQ(OK, callback.WaitForResult());
8671
8672 response = trans->GetResponseInfo();
8673 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508674 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558675 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8676 EXPECT_FALSE(response->was_fetched_via_spdy);
8677 EXPECT_FALSE(response->was_npn_negotiated);
8678
8679 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8680 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558681}
8682
[email protected]631f1322010-04-30 17:59:118683class CapturingProxyResolver : public ProxyResolver {
8684 public:
8685 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8686 virtual ~CapturingProxyResolver() {}
8687
8688 virtual int GetProxyForURL(const GURL& url,
8689 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318690 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118691 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168692 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408693 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8694 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428695 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118696 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428697 return OK;
[email protected]631f1322010-04-30 17:59:118698 }
8699
[email protected]46fadfd2013-02-06 09:40:168700 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118701 NOTREACHED();
8702 }
8703
[email protected]f2c971f2011-11-08 00:33:178704 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8705 NOTREACHED();
8706 return LOAD_STATE_IDLE;
8707 }
8708
[email protected]46fadfd2013-02-06 09:40:168709 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408710 NOTREACHED();
8711 }
8712
[email protected]24476402010-07-20 20:55:178713 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168714 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428715 return OK;
[email protected]631f1322010-04-30 17:59:118716 }
8717
[email protected]24476402010-07-20 20:55:178718 const std::vector<GURL>& resolved() const { return resolved_; }
8719
8720 private:
[email protected]631f1322010-04-30 17:59:118721 std::vector<GURL> resolved_;
8722
8723 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8724};
8725
[email protected]23e482282013-06-14 16:08:028726TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238727 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388728 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038729 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118730
8731 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428732 proxy_config.set_auto_detect(true);
8733 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118734
[email protected]631f1322010-04-30 17:59:118735 CapturingProxyResolver* capturing_proxy_resolver =
8736 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078737 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388738 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8739 NULL));
[email protected]029c83b62013-01-24 05:28:208740 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078741 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118742
8743 HttpRequestInfo request;
8744 request.method = "GET";
8745 request.url = GURL("http://www.google.com/");
8746 request.load_flags = 0;
8747
[email protected]8a0fc822013-06-27 20:52:438748 std::string alternate_protocol_http_header =
8749 GetAlternateProtocolHttpHeader();
8750
[email protected]631f1322010-04-30 17:59:118751 MockRead data_reads[] = {
8752 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438753 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118754 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178755 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068756 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118757 };
8758
8759 StaticSocketDataProvider first_transaction(
8760 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078761 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:118762
[email protected]8ddf8322012-02-23 18:08:068763 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028764 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078765 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:118766
[email protected]cdf8f7e72013-05-23 10:56:468767 scoped_ptr<SpdyFrame> req(
8768 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:118769 MockWrite spdy_writes[] = {
8770 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8771 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:428772 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:468773 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:118774 };
8775
[email protected]d911f1b2010-05-05 22:39:428776 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8777
[email protected]23e482282013-06-14 16:08:028778 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8779 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:118780 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068781 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:138782 CreateMockRead(*resp.get(), 4), // 2, 4
8783 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:068784 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:118785 };
8786
[email protected]dd54bd82012-07-19 23:44:578787 OrderedSocketData spdy_data(
8788 spdy_reads, arraysize(spdy_reads),
8789 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078790 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:118791
[email protected]d973e99a2012-02-17 21:02:368792 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558793 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8794 NULL, 0, NULL, 0);
8795 hanging_non_alternate_protocol_socket.set_connect_data(
8796 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078797 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558798 &hanging_non_alternate_protocol_socket);
8799
[email protected]49639fa2011-12-20 23:22:418800 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:118801
[email protected]bb88e1d32013-05-03 23:11:078802 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368803 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118805
[email protected]49639fa2011-12-20 23:22:418806 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118807 EXPECT_EQ(ERR_IO_PENDING, rv);
8808 EXPECT_EQ(OK, callback.WaitForResult());
8809
8810 const HttpResponseInfo* response = trans->GetResponseInfo();
8811 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508812 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118813 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538814 EXPECT_FALSE(response->was_fetched_via_spdy);
8815 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118816
8817 std::string response_data;
8818 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8819 EXPECT_EQ("hello world", response_data);
8820
[email protected]90499482013-06-01 00:39:508821 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118822
[email protected]49639fa2011-12-20 23:22:418823 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118824 EXPECT_EQ(ERR_IO_PENDING, rv);
8825 EXPECT_EQ(OK, callback.WaitForResult());
8826
8827 response = trans->GetResponseInfo();
8828 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508829 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118830 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538831 EXPECT_TRUE(response->was_fetched_via_spdy);
8832 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118833
8834 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8835 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558836 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:428837 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:118838 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:428839 EXPECT_EQ("https://www.google.com/",
8840 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:118841
[email protected]029c83b62013-01-24 05:28:208842 LoadTimingInfo load_timing_info;
8843 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8844 TestLoadTimingNotReusedWithPac(load_timing_info,
8845 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:118846}
[email protected]631f1322010-04-30 17:59:118847
[email protected]23e482282013-06-14 16:08:028848TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:548849 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:388850 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038851 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548852
8853 HttpRequestInfo request;
8854 request.method = "GET";
8855 request.url = GURL("http://www.google.com/");
8856 request.load_flags = 0;
8857
[email protected]8a0fc822013-06-27 20:52:438858 std::string alternate_protocol_http_header =
8859 GetAlternateProtocolHttpHeader();
8860
[email protected]2ff8b312010-04-26 22:20:548861 MockRead data_reads[] = {
8862 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438863 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548864 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068865 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:548866 };
8867
8868 StaticSocketDataProvider first_transaction(
8869 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078870 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548871
[email protected]8ddf8322012-02-23 18:08:068872 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028873 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548875
[email protected]cdf8f7e72013-05-23 10:56:468876 scoped_ptr<SpdyFrame> req(
8877 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138878 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548879
[email protected]23e482282013-06-14 16:08:028880 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8881 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548882 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138883 CreateMockRead(*resp),
8884 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068885 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548886 };
8887
[email protected]dd54bd82012-07-19 23:44:578888 DelayedSocketData spdy_data(
8889 1, // wait for one write to finish before reading.
8890 spdy_reads, arraysize(spdy_reads),
8891 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078892 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548893
[email protected]83039bb2011-12-09 18:43:558894 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548895
[email protected]bb88e1d32013-05-03 23:11:078896 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:548897
[email protected]262eec82013-03-19 21:01:368898 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548900
[email protected]49639fa2011-12-20 23:22:418901 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418903 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548904
8905 const HttpResponseInfo* response = trans->GetResponseInfo();
8906 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508907 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548908 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8909
8910 std::string response_data;
8911 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8912 EXPECT_EQ("hello world", response_data);
8913
8914 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:388915 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:408916 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
8917 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:278918 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:268919 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:388920
[email protected]90499482013-06-01 00:39:508921 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548922
[email protected]49639fa2011-12-20 23:22:418923 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548924 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418925 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548926
8927 response = trans->GetResponseInfo();
8928 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508929 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548930 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538931 EXPECT_TRUE(response->was_fetched_via_spdy);
8932 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548933
8934 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8935 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:428936}
8937
[email protected]044de0642010-06-17 10:42:158938// GenerateAuthToken is a mighty big test.
8939// It tests all permutation of GenerateAuthToken behavior:
8940// - Synchronous and Asynchronous completion.
8941// - OK or error on completion.
8942// - Direct connection, non-authenticating proxy, and authenticating proxy.
8943// - HTTP or HTTPS backend (to include proxy tunneling).
8944// - Non-authenticating and authenticating backend.
8945//
[email protected]fe3b7dc2012-02-03 19:52:098946// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:158947// problems generating an auth token for an authenticating proxy, we don't
8948// need to test all permutations of the backend server).
8949//
8950// The test proceeds by going over each of the configuration cases, and
8951// potentially running up to three rounds in each of the tests. The TestConfig
8952// specifies both the configuration for the test as well as the expectations
8953// for the results.
[email protected]23e482282013-06-14 16:08:028954TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:508955 static const char kServer[] = "http://www.example.com";
8956 static const char kSecureServer[] = "https://www.example.com";
8957 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:158958 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
8959
8960 enum AuthTiming {
8961 AUTH_NONE,
8962 AUTH_SYNC,
8963 AUTH_ASYNC,
8964 };
8965
8966 const MockWrite kGet(
8967 "GET / HTTP/1.1\r\n"
8968 "Host: www.example.com\r\n"
8969 "Connection: keep-alive\r\n\r\n");
8970 const MockWrite kGetProxy(
8971 "GET http://www.example.com/ HTTP/1.1\r\n"
8972 "Host: www.example.com\r\n"
8973 "Proxy-Connection: keep-alive\r\n\r\n");
8974 const MockWrite kGetAuth(
8975 "GET / HTTP/1.1\r\n"
8976 "Host: www.example.com\r\n"
8977 "Connection: keep-alive\r\n"
8978 "Authorization: auth_token\r\n\r\n");
8979 const MockWrite kGetProxyAuth(
8980 "GET http://www.example.com/ HTTP/1.1\r\n"
8981 "Host: www.example.com\r\n"
8982 "Proxy-Connection: keep-alive\r\n"
8983 "Proxy-Authorization: auth_token\r\n\r\n");
8984 const MockWrite kGetAuthThroughProxy(
8985 "GET http://www.example.com/ HTTP/1.1\r\n"
8986 "Host: www.example.com\r\n"
8987 "Proxy-Connection: keep-alive\r\n"
8988 "Authorization: auth_token\r\n\r\n");
8989 const MockWrite kGetAuthWithProxyAuth(
8990 "GET http://www.example.com/ HTTP/1.1\r\n"
8991 "Host: www.example.com\r\n"
8992 "Proxy-Connection: keep-alive\r\n"
8993 "Proxy-Authorization: auth_token\r\n"
8994 "Authorization: auth_token\r\n\r\n");
8995 const MockWrite kConnect(
8996 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8997 "Host: www.example.com\r\n"
8998 "Proxy-Connection: keep-alive\r\n\r\n");
8999 const MockWrite kConnectProxyAuth(
9000 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9001 "Host: www.example.com\r\n"
9002 "Proxy-Connection: keep-alive\r\n"
9003 "Proxy-Authorization: auth_token\r\n\r\n");
9004
9005 const MockRead kSuccess(
9006 "HTTP/1.1 200 OK\r\n"
9007 "Content-Type: text/html; charset=iso-8859-1\r\n"
9008 "Content-Length: 3\r\n\r\n"
9009 "Yes");
9010 const MockRead kFailure(
9011 "Should not be called.");
9012 const MockRead kServerChallenge(
9013 "HTTP/1.1 401 Unauthorized\r\n"
9014 "WWW-Authenticate: Mock realm=server\r\n"
9015 "Content-Type: text/html; charset=iso-8859-1\r\n"
9016 "Content-Length: 14\r\n\r\n"
9017 "Unauthorized\r\n");
9018 const MockRead kProxyChallenge(
9019 "HTTP/1.1 407 Unauthorized\r\n"
9020 "Proxy-Authenticate: Mock realm=proxy\r\n"
9021 "Proxy-Connection: close\r\n"
9022 "Content-Type: text/html; charset=iso-8859-1\r\n"
9023 "Content-Length: 14\r\n\r\n"
9024 "Unauthorized\r\n");
9025 const MockRead kProxyConnected(
9026 "HTTP/1.1 200 Connection Established\r\n\r\n");
9027
9028 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9029 // no constructors, but the C++ compiler on Windows warns about
9030 // unspecified data in compound literals. So, moved to using constructors,
9031 // and TestRound's created with the default constructor should not be used.
9032 struct TestRound {
9033 TestRound()
9034 : expected_rv(ERR_UNEXPECTED),
9035 extra_write(NULL),
9036 extra_read(NULL) {
9037 }
9038 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9039 int expected_rv_arg)
9040 : write(write_arg),
9041 read(read_arg),
9042 expected_rv(expected_rv_arg),
9043 extra_write(NULL),
9044 extra_read(NULL) {
9045 }
9046 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9047 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019048 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159049 : write(write_arg),
9050 read(read_arg),
9051 expected_rv(expected_rv_arg),
9052 extra_write(extra_write_arg),
9053 extra_read(extra_read_arg) {
9054 }
9055 MockWrite write;
9056 MockRead read;
9057 int expected_rv;
9058 const MockWrite* extra_write;
9059 const MockRead* extra_read;
9060 };
9061
9062 static const int kNoSSL = 500;
9063
9064 struct TestConfig {
9065 const char* proxy_url;
9066 AuthTiming proxy_auth_timing;
9067 int proxy_auth_rv;
9068 const char* server_url;
9069 AuthTiming server_auth_timing;
9070 int server_auth_rv;
9071 int num_auth_rounds;
9072 int first_ssl_round;
9073 TestRound rounds[3];
9074 } test_configs[] = {
9075 // Non-authenticating HTTP server with a direct connection.
9076 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9077 { TestRound(kGet, kSuccess, OK)}},
9078 // Authenticating HTTP server with a direct connection.
9079 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9080 { TestRound(kGet, kServerChallenge, OK),
9081 TestRound(kGetAuth, kSuccess, OK)}},
9082 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9083 { TestRound(kGet, kServerChallenge, OK),
9084 TestRound(kGetAuth, kFailure, kAuthErr)}},
9085 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9086 { TestRound(kGet, kServerChallenge, OK),
9087 TestRound(kGetAuth, kSuccess, OK)}},
9088 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9089 { TestRound(kGet, kServerChallenge, OK),
9090 TestRound(kGetAuth, kFailure, kAuthErr)}},
9091 // Non-authenticating HTTP server through a non-authenticating proxy.
9092 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9093 { TestRound(kGetProxy, kSuccess, OK)}},
9094 // Authenticating HTTP server through a non-authenticating proxy.
9095 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9096 { TestRound(kGetProxy, kServerChallenge, OK),
9097 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9098 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9099 { TestRound(kGetProxy, kServerChallenge, OK),
9100 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9101 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9102 { TestRound(kGetProxy, kServerChallenge, OK),
9103 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9104 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9105 { TestRound(kGetProxy, kServerChallenge, OK),
9106 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9107 // Non-authenticating HTTP server through an authenticating proxy.
9108 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9109 { TestRound(kGetProxy, kProxyChallenge, OK),
9110 TestRound(kGetProxyAuth, kSuccess, OK)}},
9111 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9112 { TestRound(kGetProxy, kProxyChallenge, OK),
9113 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9114 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9115 { TestRound(kGetProxy, kProxyChallenge, OK),
9116 TestRound(kGetProxyAuth, kSuccess, OK)}},
9117 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9118 { TestRound(kGetProxy, kProxyChallenge, OK),
9119 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9120 // Authenticating HTTP server through an authenticating proxy.
9121 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9122 { TestRound(kGetProxy, kProxyChallenge, OK),
9123 TestRound(kGetProxyAuth, kServerChallenge, OK),
9124 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9125 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9126 { TestRound(kGetProxy, kProxyChallenge, OK),
9127 TestRound(kGetProxyAuth, kServerChallenge, OK),
9128 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9129 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9130 { TestRound(kGetProxy, kProxyChallenge, OK),
9131 TestRound(kGetProxyAuth, kServerChallenge, OK),
9132 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9133 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9134 { TestRound(kGetProxy, kProxyChallenge, OK),
9135 TestRound(kGetProxyAuth, kServerChallenge, OK),
9136 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9137 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9138 { TestRound(kGetProxy, kProxyChallenge, OK),
9139 TestRound(kGetProxyAuth, kServerChallenge, OK),
9140 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9141 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9142 { TestRound(kGetProxy, kProxyChallenge, OK),
9143 TestRound(kGetProxyAuth, kServerChallenge, OK),
9144 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9145 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9146 { TestRound(kGetProxy, kProxyChallenge, OK),
9147 TestRound(kGetProxyAuth, kServerChallenge, OK),
9148 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9149 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9150 { TestRound(kGetProxy, kProxyChallenge, OK),
9151 TestRound(kGetProxyAuth, kServerChallenge, OK),
9152 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9153 // Non-authenticating HTTPS server with a direct connection.
9154 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9155 { TestRound(kGet, kSuccess, OK)}},
9156 // Authenticating HTTPS server with a direct connection.
9157 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9158 { TestRound(kGet, kServerChallenge, OK),
9159 TestRound(kGetAuth, kSuccess, OK)}},
9160 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9161 { TestRound(kGet, kServerChallenge, OK),
9162 TestRound(kGetAuth, kFailure, kAuthErr)}},
9163 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9164 { TestRound(kGet, kServerChallenge, OK),
9165 TestRound(kGetAuth, kSuccess, OK)}},
9166 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9167 { TestRound(kGet, kServerChallenge, OK),
9168 TestRound(kGetAuth, kFailure, kAuthErr)}},
9169 // Non-authenticating HTTPS server with a non-authenticating proxy.
9170 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9171 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9172 // Authenticating HTTPS server through a non-authenticating proxy.
9173 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9174 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9175 TestRound(kGetAuth, kSuccess, OK)}},
9176 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9177 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9178 TestRound(kGetAuth, kFailure, kAuthErr)}},
9179 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9180 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9181 TestRound(kGetAuth, kSuccess, OK)}},
9182 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9183 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9184 TestRound(kGetAuth, kFailure, kAuthErr)}},
9185 // Non-Authenticating HTTPS server through an authenticating proxy.
9186 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9187 { TestRound(kConnect, kProxyChallenge, OK),
9188 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9189 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9190 { TestRound(kConnect, kProxyChallenge, OK),
9191 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9192 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9193 { TestRound(kConnect, kProxyChallenge, OK),
9194 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9195 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9196 { TestRound(kConnect, kProxyChallenge, OK),
9197 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9198 // Authenticating HTTPS server through an authenticating proxy.
9199 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9200 { TestRound(kConnect, kProxyChallenge, OK),
9201 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9202 &kGet, &kServerChallenge),
9203 TestRound(kGetAuth, kSuccess, OK)}},
9204 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9205 { TestRound(kConnect, kProxyChallenge, OK),
9206 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9207 &kGet, &kServerChallenge),
9208 TestRound(kGetAuth, kFailure, kAuthErr)}},
9209 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9210 { TestRound(kConnect, kProxyChallenge, OK),
9211 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9212 &kGet, &kServerChallenge),
9213 TestRound(kGetAuth, kSuccess, OK)}},
9214 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9215 { TestRound(kConnect, kProxyChallenge, OK),
9216 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9217 &kGet, &kServerChallenge),
9218 TestRound(kGetAuth, kFailure, kAuthErr)}},
9219 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9220 { TestRound(kConnect, kProxyChallenge, OK),
9221 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9222 &kGet, &kServerChallenge),
9223 TestRound(kGetAuth, kSuccess, OK)}},
9224 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9225 { TestRound(kConnect, kProxyChallenge, OK),
9226 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9227 &kGet, &kServerChallenge),
9228 TestRound(kGetAuth, kFailure, kAuthErr)}},
9229 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9230 { TestRound(kConnect, kProxyChallenge, OK),
9231 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9232 &kGet, &kServerChallenge),
9233 TestRound(kGetAuth, kSuccess, OK)}},
9234 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9235 { TestRound(kConnect, kProxyChallenge, OK),
9236 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9237 &kGet, &kServerChallenge),
9238 TestRound(kGetAuth, kFailure, kAuthErr)}},
9239 };
9240
[email protected]044de0642010-06-17 10:42:159241 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089242 HttpAuthHandlerMock::Factory* auth_factory(
9243 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079244 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159245 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269246
9247 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159248 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089249 for (int n = 0; n < 2; n++) {
9250 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9251 std::string auth_challenge = "Mock realm=proxy";
9252 GURL origin(test_config.proxy_url);
9253 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9254 auth_challenge.end());
9255 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9256 origin, BoundNetLog());
9257 auth_handler->SetGenerateExpectation(
9258 test_config.proxy_auth_timing == AUTH_ASYNC,
9259 test_config.proxy_auth_rv);
9260 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9261 }
[email protected]044de0642010-06-17 10:42:159262 }
9263 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009264 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159265 std::string auth_challenge = "Mock realm=server";
9266 GURL origin(test_config.server_url);
9267 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9268 auth_challenge.end());
9269 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9270 origin, BoundNetLog());
9271 auth_handler->SetGenerateExpectation(
9272 test_config.server_auth_timing == AUTH_ASYNC,
9273 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089274 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159275 }
9276 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079277 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129278 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159279 } else {
[email protected]bb88e1d32013-05-03 23:11:079280 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159281 }
9282
9283 HttpRequestInfo request;
9284 request.method = "GET";
9285 request.url = GURL(test_config.server_url);
9286 request.load_flags = 0;
9287
[email protected]bb88e1d32013-05-03 23:11:079288 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369289 HttpNetworkTransaction trans(
[email protected]bb88e1d32013-05-03 23:11:079290 DEFAULT_PRIORITY, CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:159291
9292 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9293 const TestRound& read_write_round = test_config.rounds[round];
9294
9295 // Set up expected reads and writes.
9296 MockRead reads[2];
9297 reads[0] = read_write_round.read;
9298 size_t length_reads = 1;
9299 if (read_write_round.extra_read) {
9300 reads[1] = *read_write_round.extra_read;
9301 length_reads = 2;
9302 }
9303
9304 MockWrite writes[2];
9305 writes[0] = read_write_round.write;
9306 size_t length_writes = 1;
9307 if (read_write_round.extra_write) {
9308 writes[1] = *read_write_round.extra_write;
9309 length_writes = 2;
9310 }
9311 StaticSocketDataProvider data_provider(
9312 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079313 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159314
9315 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069316 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159317 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079318 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159319 &ssl_socket_data_provider);
9320
9321 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419322 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159323 int rv;
9324 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419325 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159326 } else {
[email protected]49639fa2011-12-20 23:22:419327 rv = trans.RestartWithAuth(
9328 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159329 }
9330 if (rv == ERR_IO_PENDING)
9331 rv = callback.WaitForResult();
9332
9333 // Compare results with expected data.
9334 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509335 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159336 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509337 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159338 } else {
9339 EXPECT_TRUE(response == NULL);
9340 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9341 continue;
9342 }
9343 if (round + 1 < test_config.num_auth_rounds) {
9344 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9345 } else {
9346 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9347 }
9348 }
[email protected]e5ae96a2010-04-14 20:12:459349 }
9350}
9351
[email protected]23e482282013-06-14 16:08:029352TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149353 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149354 HttpAuthHandlerMock::Factory* auth_factory(
9355 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079356 session_deps_.http_auth_handler_factory.reset(auth_factory);
9357 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9358 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9359 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149360
9361 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9362 auth_handler->set_connection_based(true);
9363 std::string auth_challenge = "Mock realm=server";
9364 GURL origin("http://www.example.com");
9365 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9366 auth_challenge.end());
9367 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9368 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089369 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149370
[email protected]c871bce92010-07-15 21:51:149371 int rv = OK;
9372 const HttpResponseInfo* response = NULL;
9373 HttpRequestInfo request;
9374 request.method = "GET";
9375 request.url = origin;
9376 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279377
[email protected]bb88e1d32013-05-03 23:11:079378 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109379
9380 // Use a TCP Socket Pool with only one connection per group. This is used
9381 // to validate that the TCP socket is not released to the pool between
9382 // each round of multi-round authentication.
9383 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289384 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9385 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109386 50, // Max sockets for pool
9387 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289388 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079389 session_deps_.host_resolver.get(),
9390 session_deps_.socket_factory.get(),
9391 session_deps_.net_log);
[email protected]a42dbd142011-11-17 16:42:029392 MockClientSocketPoolManager* mock_pool_manager =
9393 new MockClientSocketPoolManager;
9394 mock_pool_manager->SetTransportSocketPool(transport_pool);
9395 session_peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]7ef4cbbb2011-02-06 11:19:109396
[email protected]262eec82013-03-19 21:01:369397 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509398 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419399 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149400
9401 const MockWrite kGet(
9402 "GET / HTTP/1.1\r\n"
9403 "Host: www.example.com\r\n"
9404 "Connection: keep-alive\r\n\r\n");
9405 const MockWrite kGetAuth(
9406 "GET / HTTP/1.1\r\n"
9407 "Host: www.example.com\r\n"
9408 "Connection: keep-alive\r\n"
9409 "Authorization: auth_token\r\n\r\n");
9410
9411 const MockRead kServerChallenge(
9412 "HTTP/1.1 401 Unauthorized\r\n"
9413 "WWW-Authenticate: Mock realm=server\r\n"
9414 "Content-Type: text/html; charset=iso-8859-1\r\n"
9415 "Content-Length: 14\r\n\r\n"
9416 "Unauthorized\r\n");
9417 const MockRead kSuccess(
9418 "HTTP/1.1 200 OK\r\n"
9419 "Content-Type: text/html; charset=iso-8859-1\r\n"
9420 "Content-Length: 3\r\n\r\n"
9421 "Yes");
9422
9423 MockWrite writes[] = {
9424 // First round
9425 kGet,
9426 // Second round
9427 kGetAuth,
9428 // Third round
9429 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309430 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109431 kGetAuth,
9432 // Competing request
9433 kGet,
[email protected]c871bce92010-07-15 21:51:149434 };
9435 MockRead reads[] = {
9436 // First round
9437 kServerChallenge,
9438 // Second round
9439 kServerChallenge,
9440 // Third round
[email protected]eca50e122010-09-11 14:03:309441 kServerChallenge,
9442 // Fourth round
[email protected]c871bce92010-07-15 21:51:149443 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109444 // Competing response
9445 kSuccess,
[email protected]c871bce92010-07-15 21:51:149446 };
9447 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9448 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079449 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149450
[email protected]7ef4cbbb2011-02-06 11:19:109451 const char* const kSocketGroup = "www.example.com:80";
9452
9453 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149454 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419455 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149456 if (rv == ERR_IO_PENDING)
9457 rv = callback.WaitForResult();
9458 EXPECT_EQ(OK, rv);
9459 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509460 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149461 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289462 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149463
[email protected]7ef4cbbb2011-02-06 11:19:109464 // In between rounds, another request comes in for the same domain.
9465 // It should not be able to grab the TCP socket that trans has already
9466 // claimed.
9467 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509468 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419469 TestCompletionCallback callback_compete;
9470 rv = trans_compete->Start(
9471 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109472 EXPECT_EQ(ERR_IO_PENDING, rv);
9473 // callback_compete.WaitForResult at this point would stall forever,
9474 // since the HttpNetworkTransaction does not release the request back to
9475 // the pool until after authentication completes.
9476
9477 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149478 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419479 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149480 if (rv == ERR_IO_PENDING)
9481 rv = callback.WaitForResult();
9482 EXPECT_EQ(OK, rv);
9483 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509484 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149485 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289486 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149487
[email protected]7ef4cbbb2011-02-06 11:19:109488 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149489 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419490 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149491 if (rv == ERR_IO_PENDING)
9492 rv = callback.WaitForResult();
9493 EXPECT_EQ(OK, rv);
9494 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509495 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149496 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289497 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309498
[email protected]7ef4cbbb2011-02-06 11:19:109499 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309500 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419501 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309502 if (rv == ERR_IO_PENDING)
9503 rv = callback.WaitForResult();
9504 EXPECT_EQ(OK, rv);
9505 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509506 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309507 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289508 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109509
9510 // Read the body since the fourth round was successful. This will also
9511 // release the socket back to the pool.
9512 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509513 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109514 if (rv == ERR_IO_PENDING)
9515 rv = callback.WaitForResult();
9516 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509517 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109518 EXPECT_EQ(0, rv);
9519 // There are still 0 idle sockets, since the trans_compete transaction
9520 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289521 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109522
9523 // The competing request can now finish. Wait for the headers and then
9524 // read the body.
9525 rv = callback_compete.WaitForResult();
9526 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509527 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109528 if (rv == ERR_IO_PENDING)
9529 rv = callback.WaitForResult();
9530 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509531 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109532 EXPECT_EQ(0, rv);
9533
9534 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289535 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149536}
9537
[email protected]65041fa2010-05-21 06:56:539538// This tests the case that a request is issued via http instead of spdy after
9539// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029540TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389541 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169542 std::vector<NextProto> next_protos;
9543 next_protos.push_back(kProtoHTTP11);
9544 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539545 HttpRequestInfo request;
9546 request.method = "GET";
9547 request.url = GURL("https://www.google.com/");
9548 request.load_flags = 0;
9549
9550 MockWrite data_writes[] = {
9551 MockWrite("GET / HTTP/1.1\r\n"
9552 "Host: www.google.com\r\n"
9553 "Connection: keep-alive\r\n\r\n"),
9554 };
9555
[email protected]8a0fc822013-06-27 20:52:439556 std::string alternate_protocol_http_header =
9557 GetAlternateProtocolHttpHeader();
9558
[email protected]65041fa2010-05-21 06:56:539559 MockRead data_reads[] = {
9560 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439561 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539562 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069563 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539564 };
9565
[email protected]8ddf8322012-02-23 18:08:069566 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539567 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9568 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469569 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539570
[email protected]bb88e1d32013-05-03 23:11:079571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539572
9573 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9574 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079575 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539576
[email protected]49639fa2011-12-20 23:22:419577 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539578
[email protected]bb88e1d32013-05-03 23:11:079579 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369580 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539582
[email protected]49639fa2011-12-20 23:22:419583 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539584
9585 EXPECT_EQ(ERR_IO_PENDING, rv);
9586 EXPECT_EQ(OK, callback.WaitForResult());
9587
9588 const HttpResponseInfo* response = trans->GetResponseInfo();
9589 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509590 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539591 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9592
9593 std::string response_data;
9594 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9595 EXPECT_EQ("hello world", response_data);
9596
9597 EXPECT_FALSE(response->was_fetched_via_spdy);
9598 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539599}
[email protected]26ef6582010-06-24 02:30:479600
[email protected]23e482282013-06-14 16:08:029601TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479602 // Simulate the SSL handshake completing with an NPN negotiation
9603 // followed by an immediate server closing of the socket.
9604 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389605 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039606 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479607
9608 HttpRequestInfo request;
9609 request.method = "GET";
9610 request.url = GURL("https://www.google.com/");
9611 request.load_flags = 0;
9612
[email protected]8ddf8322012-02-23 18:08:069613 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029614 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479616
[email protected]cdf8f7e72013-05-23 10:56:469617 scoped_ptr<SpdyFrame> req(
9618 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139619 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479620
9621 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069622 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479623 };
9624
[email protected]dd54bd82012-07-19 23:44:579625 DelayedSocketData spdy_data(
9626 0, // don't wait in this case, immediate hangup.
9627 spdy_reads, arraysize(spdy_reads),
9628 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079629 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479630
[email protected]49639fa2011-12-20 23:22:419631 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479632
[email protected]bb88e1d32013-05-03 23:11:079633 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369634 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509635 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479636
[email protected]49639fa2011-12-20 23:22:419637 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479638 EXPECT_EQ(ERR_IO_PENDING, rv);
9639 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479640}
[email protected]65d34382010-07-01 18:12:269641
[email protected]795cbf82013-07-22 09:37:279642// A subclass of HttpAuthHandlerMock that records the request URL when
9643// it gets it. This is needed since the auth handler may get destroyed
9644// before we get a chance to query it.
9645class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9646 public:
9647 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9648
9649 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9650
9651 protected:
9652 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9653 const HttpRequestInfo* request,
9654 const CompletionCallback& callback,
9655 std::string* auth_token) OVERRIDE {
9656 *url_ = request->url;
9657 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9658 credentials, request, callback, auth_token);
9659 }
9660
9661 private:
9662 GURL* url_;
9663};
9664
[email protected]23e482282013-06-14 16:08:029665TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309666 // This test ensures that the URL passed into the proxy is upgraded
9667 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389668 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439669 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309670
[email protected]bb88e1d32013-05-03 23:11:079671 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209672 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9673 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079674 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279675 GURL request_url;
9676 {
9677 HttpAuthHandlerMock::Factory* auth_factory =
9678 new HttpAuthHandlerMock::Factory();
9679 UrlRecordingHttpAuthHandlerMock* auth_handler =
9680 new UrlRecordingHttpAuthHandlerMock(&request_url);
9681 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9682 auth_factory->set_do_init_from_challenge(true);
9683 session_deps_.http_auth_handler_factory.reset(auth_factory);
9684 }
[email protected]f45c1ee2010-08-03 00:54:309685
9686 HttpRequestInfo request;
9687 request.method = "GET";
9688 request.url = GURL("http://www.google.com");
9689 request.load_flags = 0;
9690
9691 // First round goes unauthenticated through the proxy.
9692 MockWrite data_writes_1[] = {
9693 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9694 "Host: www.google.com\r\n"
9695 "Proxy-Connection: keep-alive\r\n"
9696 "\r\n"),
9697 };
9698 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069699 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309700 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239701 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309702 "Proxy-Connection: close\r\n"
9703 "\r\n"),
9704 };
9705 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9706 data_writes_1, arraysize(data_writes_1));
9707
9708 // Second round tries to tunnel to www.google.com due to the
9709 // Alternate-Protocol announcement in the first round. It fails due
9710 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599711 // After the failure, a tunnel is established to www.google.com using
9712 // Proxy-Authorization headers. There is then a SPDY request round.
9713 //
[email protected]fe3b7dc2012-02-03 19:52:099714 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9715 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9716 // does a Disconnect and Connect on the same socket, rather than trying
9717 // to obtain a new one.
9718 //
[email protected]394816e92010-08-03 07:38:599719 // NOTE: Originally, the proxy response to the second CONNECT request
9720 // simply returned another 407 so the unit test could skip the SSL connection
9721 // establishment and SPDY framing issues. Alas, the
9722 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309723 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599724
[email protected]cdf8f7e72013-05-23 10:56:469725 scoped_ptr<SpdyFrame> req(
9726 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029727 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9728 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309729
[email protected]394816e92010-08-03 07:38:599730 MockWrite data_writes_2[] = {
9731 // First connection attempt without Proxy-Authorization.
9732 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9733 "Host: www.google.com\r\n"
9734 "Proxy-Connection: keep-alive\r\n"
9735 "\r\n"),
9736
9737 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309738 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9739 "Host: www.google.com\r\n"
9740 "Proxy-Connection: keep-alive\r\n"
9741 "Proxy-Authorization: auth_token\r\n"
9742 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309743
[email protected]394816e92010-08-03 07:38:599744 // SPDY request
9745 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309746 };
[email protected]394816e92010-08-03 07:38:599747 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9748 "Proxy-Authenticate: Mock\r\n"
9749 "Proxy-Connection: close\r\n"
9750 "\r\n");
9751 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9752 MockRead data_reads_2[] = {
9753 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069754 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9755 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599756 arraysize(kRejectConnectResponse) - 1, 1),
9757
9758 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069759 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:099760 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:599761
9762 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:099763 CreateMockRead(*resp.get(), 6),
9764 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:069765 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:599766 };
[email protected]dd54bd82012-07-19 23:44:579767 OrderedSocketData data_2(
9768 data_reads_2, arraysize(data_reads_2),
9769 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:309770
[email protected]8ddf8322012-02-23 18:08:069771 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029772 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:309773
[email protected]d973e99a2012-02-17 21:02:369774 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559775 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9776 NULL, 0, NULL, 0);
9777 hanging_non_alternate_protocol_socket.set_connect_data(
9778 never_finishing_connect);
9779
[email protected]bb88e1d32013-05-03 23:11:079780 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9781 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9782 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9783 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559784 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:079785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:309786
9787 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:419788 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:369789 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:509790 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419791 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309792 EXPECT_EQ(ERR_IO_PENDING, rv);
9793 EXPECT_EQ(OK, callback_1.WaitForResult());
9794
9795 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:419796 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:369797 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:509798 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419799 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309800 EXPECT_EQ(ERR_IO_PENDING, rv);
9801 EXPECT_EQ(OK, callback_2.WaitForResult());
9802 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509803 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:309804 ASSERT_FALSE(response->auth_challenge.get() == NULL);
9805
9806 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:419807 TestCompletionCallback callback_3;
9808 rv = trans_2->RestartWithAuth(
9809 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:309810 EXPECT_EQ(ERR_IO_PENDING, rv);
9811 EXPECT_EQ(OK, callback_3.WaitForResult());
9812
9813 // After all that work, these two lines (or actually, just the scheme) are
9814 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:309815 EXPECT_EQ("https", request_url.scheme());
9816 EXPECT_EQ("www.google.com", request_url.host());
9817
[email protected]029c83b62013-01-24 05:28:209818 LoadTimingInfo load_timing_info;
9819 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9820 TestLoadTimingNotReusedWithPac(load_timing_info,
9821 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:389822}
9823
9824// Test that if we cancel the transaction as the connection is completing, that
9825// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:029826TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:389827 // Setup everything about the connection to complete synchronously, so that
9828 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9829 // for is the callback from the HttpStreamRequest.
9830 // Then cancel the transaction.
9831 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:369832 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:389833 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069834 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9835 MockRead(SYNCHRONOUS, "hello world"),
9836 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:389837 };
9838
[email protected]8e6441ca2010-08-19 05:56:389839 HttpRequestInfo request;
9840 request.method = "GET";
9841 request.url = GURL("http://www.google.com/");
9842 request.load_flags = 0;
9843
[email protected]bb88e1d32013-05-03 23:11:079844 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]cb9bf6ca2011-01-28 13:15:279845 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:369846 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:079847 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:279848
[email protected]8e6441ca2010-08-19 05:56:389849 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9850 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079851 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:389852
[email protected]49639fa2011-12-20 23:22:419853 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:389854
[email protected]333bdf62012-06-08 22:57:299855 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:419856 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:389857 EXPECT_EQ(ERR_IO_PENDING, rv);
9858 trans.reset(); // Cancel the transaction here.
9859
[email protected]2da659e2013-05-23 20:51:349860 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:309861}
9862
[email protected]76a505b2010-08-25 06:23:009863// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029864TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:079865 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209866 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299867 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079868 session_deps_.net_log = log.bound().net_log();
9869 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009870
[email protected]76a505b2010-08-25 06:23:009871 HttpRequestInfo request;
9872 request.method = "GET";
9873 request.url = GURL("http://www.google.com/");
9874
9875 MockWrite data_writes1[] = {
9876 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9877 "Host: www.google.com\r\n"
9878 "Proxy-Connection: keep-alive\r\n\r\n"),
9879 };
9880
9881 MockRead data_reads1[] = {
9882 MockRead("HTTP/1.1 200 OK\r\n"),
9883 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9884 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069885 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009886 };
9887
9888 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9889 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079890 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:009891
[email protected]49639fa2011-12-20 23:22:419892 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009893
[email protected]262eec82013-03-19 21:01:369894 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509896
[email protected]49639fa2011-12-20 23:22:419897 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009898 EXPECT_EQ(ERR_IO_PENDING, rv);
9899
9900 rv = callback1.WaitForResult();
9901 EXPECT_EQ(OK, rv);
9902
9903 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509904 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009905
9906 EXPECT_TRUE(response->headers->IsKeepAlive());
9907 EXPECT_EQ(200, response->headers->response_code());
9908 EXPECT_EQ(100, response->headers->GetContentLength());
9909 EXPECT_TRUE(response->was_fetched_via_proxy);
9910 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209911
9912 LoadTimingInfo load_timing_info;
9913 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9914 TestLoadTimingNotReusedWithPac(load_timing_info,
9915 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:009916}
9917
9918// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029919TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:079920 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209921 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299922 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079923 session_deps_.net_log = log.bound().net_log();
9924 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009925
[email protected]76a505b2010-08-25 06:23:009926 HttpRequestInfo request;
9927 request.method = "GET";
9928 request.url = GURL("https://www.google.com/");
9929
9930 // Since we have proxy, should try to establish tunnel.
9931 MockWrite data_writes1[] = {
9932 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9933 "Host: www.google.com\r\n"
9934 "Proxy-Connection: keep-alive\r\n\r\n"),
9935
9936 MockWrite("GET / HTTP/1.1\r\n"
9937 "Host: www.google.com\r\n"
9938 "Connection: keep-alive\r\n\r\n"),
9939 };
9940
9941 MockRead data_reads1[] = {
9942 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
9943
9944 MockRead("HTTP/1.1 200 OK\r\n"),
9945 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9946 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069947 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009948 };
9949
9950 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9951 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069953 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079954 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009955
[email protected]49639fa2011-12-20 23:22:419956 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009957
[email protected]262eec82013-03-19 21:01:369958 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509959 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509960
[email protected]49639fa2011-12-20 23:22:419961 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009962 EXPECT_EQ(ERR_IO_PENDING, rv);
9963
9964 rv = callback1.WaitForResult();
9965 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:579966 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409967 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009968 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409969 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009970 NetLog::PHASE_NONE);
9971 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409972 entries, pos,
[email protected]76a505b2010-08-25 06:23:009973 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9974 NetLog::PHASE_NONE);
9975
9976 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509977 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009978
9979 EXPECT_TRUE(response->headers->IsKeepAlive());
9980 EXPECT_EQ(200, response->headers->response_code());
9981 EXPECT_EQ(100, response->headers->GetContentLength());
9982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9983 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:209984
9985 LoadTimingInfo load_timing_info;
9986 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9987 TestLoadTimingNotReusedWithPac(load_timing_info,
9988 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:009989}
9990
9991// Test a basic HTTPS GET request through a proxy, but the server hangs up
9992// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:029993TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:079994 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299995 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079996 session_deps_.net_log = log.bound().net_log();
9997 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009998
[email protected]76a505b2010-08-25 06:23:009999 HttpRequestInfo request;
10000 request.method = "GET";
10001 request.url = GURL("https://www.google.com/");
10002
10003 // Since we have proxy, should try to establish tunnel.
10004 MockWrite data_writes1[] = {
10005 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10006 "Host: www.google.com\r\n"
10007 "Proxy-Connection: keep-alive\r\n\r\n"),
10008
10009 MockWrite("GET / HTTP/1.1\r\n"
10010 "Host: www.google.com\r\n"
10011 "Connection: keep-alive\r\n\r\n"),
10012 };
10013
10014 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610015 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010016 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610017 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010018 };
10019
10020 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10021 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710022 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610023 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010025
[email protected]49639fa2011-12-20 23:22:4110026 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010027
[email protected]262eec82013-03-19 21:01:3610028 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010030
[email protected]49639fa2011-12-20 23:22:4110031 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010032 EXPECT_EQ(ERR_IO_PENDING, rv);
10033
10034 rv = callback1.WaitForResult();
10035 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710036 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010037 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010038 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010039 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010040 NetLog::PHASE_NONE);
10041 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010042 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010043 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10044 NetLog::PHASE_NONE);
10045}
10046
[email protected]749eefa82010-09-13 22:14:0310047// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210048TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610049 scoped_ptr<SpdyFrame> req(
10050 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310051 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10052
[email protected]23e482282013-06-14 16:08:0210053 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10054 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310055 MockRead spdy_reads[] = {
10056 CreateMockRead(*resp),
10057 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610058 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310059 };
10060
[email protected]dd54bd82012-07-19 23:44:5710061 DelayedSocketData spdy_data(
10062 1, // wait for one write to finish before reading.
10063 spdy_reads, arraysize(spdy_reads),
10064 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710065 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310066
[email protected]8ddf8322012-02-23 18:08:0610067 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210068 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310070
[email protected]bb88e1d32013-05-03 23:11:0710071 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310072
10073 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810074 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010075 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10076 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:2710077 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610078 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310079
10080 HttpRequestInfo request;
10081 request.method = "GET";
10082 request.url = GURL("https://www.google.com/");
10083 request.load_flags = 0;
10084
10085 // This is the important line that marks this as a preconnect.
10086 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10087
[email protected]262eec82013-03-19 21:01:3610088 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010089 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310090
[email protected]41d64e82013-07-03 22:44:2610091 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110092 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310093 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110094 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310095}
10096
[email protected]73b8dd222010-11-11 19:55:2410097// Given a net error, cause that error to be returned from the first Write()
10098// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210099void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710100 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710101 net::HttpRequestInfo request_info;
10102 request_info.url = GURL("https://www.example.com/");
10103 request_info.method = "GET";
10104 request_info.load_flags = net::LOAD_NORMAL;
10105
[email protected]8ddf8322012-02-23 18:08:0610106 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410107 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610108 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410109 };
10110 net::StaticSocketDataProvider data(NULL, 0,
10111 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710112 session_deps_.socket_factory->AddSocketDataProvider(&data);
10113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410114
[email protected]bb88e1d32013-05-03 23:11:0710115 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610116 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410118
[email protected]49639fa2011-12-20 23:22:4110119 TestCompletionCallback callback;
10120 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410121 if (rv == net::ERR_IO_PENDING)
10122 rv = callback.WaitForResult();
10123 ASSERT_EQ(error, rv);
10124}
10125
[email protected]23e482282013-06-14 16:08:0210126TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410127 // Just check a grab bag of cert errors.
10128 static const int kErrors[] = {
10129 ERR_CERT_COMMON_NAME_INVALID,
10130 ERR_CERT_AUTHORITY_INVALID,
10131 ERR_CERT_DATE_INVALID,
10132 };
10133 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610134 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10135 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410136 }
10137}
10138
[email protected]bd0b6772011-01-11 19:59:3010139// Ensure that a client certificate is removed from the SSL client auth
10140// cache when:
10141// 1) No proxy is involved.
10142// 2) TLS False Start is disabled.
10143// 3) The initial TLS handshake requests a client certificate.
10144// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210145TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310146 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710147 net::HttpRequestInfo request_info;
10148 request_info.url = GURL("https://www.example.com/");
10149 request_info.method = "GET";
10150 request_info.load_flags = net::LOAD_NORMAL;
10151
[email protected]bd0b6772011-01-11 19:59:3010152 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10153 cert_request->host_and_port = "www.example.com:443";
10154
10155 // [ssl_]data1 contains the data for the first SSL handshake. When a
10156 // CertificateRequest is received for the first time, the handshake will
10157 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610158 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010159 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010161 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710162 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010163
10164 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10165 // False Start is not being used, the result of the SSL handshake will be
10166 // returned as part of the SSLClientSocket::Connect() call. This test
10167 // matches the result of a server sending a handshake_failure alert,
10168 // rather than a Finished message, because it requires a client
10169 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610170 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010171 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010173 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710174 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010175
10176 // [ssl_]data3 contains the data for the third SSL handshake. When a
10177 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710178 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10179 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010180 // of the HttpNetworkTransaction. Because this test failure is due to
10181 // requiring a client certificate, this fallback handshake should also
10182 // fail.
[email protected]8ddf8322012-02-23 18:08:0610183 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010184 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010186 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710187 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010188
[email protected]80c75f682012-05-26 16:22:1710189 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10190 // connection to a server fails during an SSL handshake,
10191 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10192 // connection was attempted with TLSv1. This is transparent to the caller
10193 // of the HttpNetworkTransaction. Because this test failure is due to
10194 // requiring a client certificate, this fallback handshake should also
10195 // fail.
10196 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10197 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710199 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710200 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710201
[email protected]7799de12013-05-30 05:52:5110202 // Need one more if TLSv1.2 is enabled.
10203 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10204 ssl_data5.cert_request_info = cert_request.get();
10205 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10206 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10207 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10208
[email protected]bb88e1d32013-05-03 23:11:0710209 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610210 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010212
[email protected]bd0b6772011-01-11 19:59:3010213 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110214 TestCompletionCallback callback;
10215 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010216 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10217
10218 // Complete the SSL handshake, which should abort due to requiring a
10219 // client certificate.
10220 rv = callback.WaitForResult();
10221 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10222
10223 // Indicate that no certificate should be supplied. From the perspective
10224 // of SSLClientCertCache, NULL is just as meaningful as a real
10225 // certificate, so this is the same as supply a
10226 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110227 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010228 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10229
10230 // Ensure the certificate was added to the client auth cache before
10231 // allowing the connection to continue restarting.
10232 scoped_refptr<X509Certificate> client_cert;
10233 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10234 &client_cert));
10235 ASSERT_EQ(NULL, client_cert.get());
10236
10237 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710238 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10239 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010240 rv = callback.WaitForResult();
10241 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10242
10243 // Ensure that the client certificate is removed from the cache on a
10244 // handshake failure.
10245 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10246 &client_cert));
10247}
10248
10249// Ensure that a client certificate is removed from the SSL client auth
10250// cache when:
10251// 1) No proxy is involved.
10252// 2) TLS False Start is enabled.
10253// 3) The initial TLS handshake requests a client certificate.
10254// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210255TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310256 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710257 net::HttpRequestInfo request_info;
10258 request_info.url = GURL("https://www.example.com/");
10259 request_info.method = "GET";
10260 request_info.load_flags = net::LOAD_NORMAL;
10261
[email protected]bd0b6772011-01-11 19:59:3010262 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10263 cert_request->host_and_port = "www.example.com:443";
10264
10265 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10266 // return successfully after reading up to the peer's Certificate message.
10267 // This is to allow the caller to call SSLClientSocket::Write(), which can
10268 // enqueue application data to be sent in the same packet as the
10269 // ChangeCipherSpec and Finished messages.
10270 // The actual handshake will be finished when SSLClientSocket::Read() is
10271 // called, which expects to process the peer's ChangeCipherSpec and
10272 // Finished messages. If there was an error negotiating with the peer,
10273 // such as due to the peer requiring a client certificate when none was
10274 // supplied, the alert sent by the peer won't be processed until Read() is
10275 // called.
10276
10277 // Like the non-False Start case, when a client certificate is requested by
10278 // the peer, the handshake is aborted during the Connect() call.
10279 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610280 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010281 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010283 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710284 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010285
10286 // When a client certificate is supplied, Connect() will not be aborted
10287 // when the peer requests the certificate. Instead, the handshake will
10288 // artificially succeed, allowing the caller to write the HTTP request to
10289 // the socket. The handshake messages are not processed until Read() is
10290 // called, which then detects that the handshake was aborted, due to the
10291 // peer sending a handshake_failure because it requires a client
10292 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610293 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010294 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710295 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010296 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610297 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010298 };
10299 net::StaticSocketDataProvider data2(
10300 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710301 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010302
10303 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710304 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10305 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610306 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010307 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010309 net::StaticSocketDataProvider data3(
10310 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710311 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010312
[email protected]80c75f682012-05-26 16:22:1710313 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10314 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10315 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10316 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710318 net::StaticSocketDataProvider data4(
10319 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710320 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710321
[email protected]7799de12013-05-30 05:52:5110322 // Need one more if TLSv1.2 is enabled.
10323 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10324 ssl_data5.cert_request_info = cert_request.get();
10325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10326 net::StaticSocketDataProvider data5(
10327 data2_reads, arraysize(data2_reads), NULL, 0);
10328 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10329
[email protected]bb88e1d32013-05-03 23:11:0710330 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610331 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010332 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010333
[email protected]bd0b6772011-01-11 19:59:3010334 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110335 TestCompletionCallback callback;
10336 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010337 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10338
10339 // Complete the SSL handshake, which should abort due to requiring a
10340 // client certificate.
10341 rv = callback.WaitForResult();
10342 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10343
10344 // Indicate that no certificate should be supplied. From the perspective
10345 // of SSLClientCertCache, NULL is just as meaningful as a real
10346 // certificate, so this is the same as supply a
10347 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110348 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010349 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10350
10351 // Ensure the certificate was added to the client auth cache before
10352 // allowing the connection to continue restarting.
10353 scoped_refptr<X509Certificate> client_cert;
10354 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10355 &client_cert));
10356 ASSERT_EQ(NULL, client_cert.get());
10357
[email protected]bd0b6772011-01-11 19:59:3010358 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710359 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10360 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010361 rv = callback.WaitForResult();
10362 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10363
10364 // Ensure that the client certificate is removed from the cache on a
10365 // handshake failure.
10366 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10367 &client_cert));
10368}
10369
[email protected]8c405132011-01-11 22:03:1810370// Ensure that a client certificate is removed from the SSL client auth
10371// cache when:
10372// 1) An HTTPS proxy is involved.
10373// 3) The HTTPS proxy requests a client certificate.
10374// 4) The client supplies an invalid/unacceptable certificate for the
10375// proxy.
10376// The test is repeated twice, first for connecting to an HTTPS endpoint,
10377// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210378TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710379 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810380 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910381 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710382 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810383
10384 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10385 cert_request->host_and_port = "proxy:70";
10386
10387 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10388 // [ssl_]data[1-3]. Rather than represending the endpoint
10389 // (www.example.com:443), they represent failures with the HTTPS proxy
10390 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610391 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810392 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710393 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810394 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710395 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810396
[email protected]8ddf8322012-02-23 18:08:0610397 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810398 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810400 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710401 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810402
[email protected]80c75f682012-05-26 16:22:1710403 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10404#if 0
[email protected]8ddf8322012-02-23 18:08:0610405 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810406 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810408 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710409 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710410#endif
[email protected]8c405132011-01-11 22:03:1810411
10412 net::HttpRequestInfo requests[2];
10413 requests[0].url = GURL("https://www.example.com/");
10414 requests[0].method = "GET";
10415 requests[0].load_flags = net::LOAD_NORMAL;
10416
10417 requests[1].url = GURL("http://www.example.com/");
10418 requests[1].method = "GET";
10419 requests[1].load_flags = net::LOAD_NORMAL;
10420
10421 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710422 session_deps_.socket_factory->ResetNextMockIndexes();
10423 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810424 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010425 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810426
10427 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110428 TestCompletionCallback callback;
10429 int rv = trans->Start(
10430 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810431 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10432
10433 // Complete the SSL handshake, which should abort due to requiring a
10434 // client certificate.
10435 rv = callback.WaitForResult();
10436 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10437
10438 // Indicate that no certificate should be supplied. From the perspective
10439 // of SSLClientCertCache, NULL is just as meaningful as a real
10440 // certificate, so this is the same as supply a
10441 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110442 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810443 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10444
10445 // Ensure the certificate was added to the client auth cache before
10446 // allowing the connection to continue restarting.
10447 scoped_refptr<X509Certificate> client_cert;
10448 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10449 &client_cert));
10450 ASSERT_EQ(NULL, client_cert.get());
10451 // Ensure the certificate was NOT cached for the endpoint. This only
10452 // applies to HTTPS requests, but is fine to check for HTTP requests.
10453 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10454 &client_cert));
10455
10456 // Restart the handshake. This will consume ssl_data2, which fails, and
10457 // then consume ssl_data3, which should also fail. The result code is
10458 // checked against what ssl_data3 should return.
10459 rv = callback.WaitForResult();
10460 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10461
10462 // Now that the new handshake has failed, ensure that the client
10463 // certificate was removed from the client auth cache.
10464 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10465 &client_cert));
10466 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10467 &client_cert));
10468 }
10469}
10470
[email protected]23e482282013-06-14 16:08:0210471// Unlike TEST/TEST_F, which are macros that expand to further macros,
10472// TEST_P is a macro that expands directly to code that stringizes the
10473// arguments. As a result, macros passed as parameters (such as prefix
10474// or test_case_name) will not be expanded by the preprocessor. To
10475// work around this, indirect the macro for TEST_P, so that the
10476// pre-processor will expand macros such as MAYBE_test_name before
10477// instantiating the test.
10478#define WRAPPED_TEST_P(test_case_name, test_name) \
10479 TEST_P(test_case_name, test_name)
10480
[email protected]45b170822012-05-04 21:18:1410481// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10482#if defined(OS_WIN)
10483#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10484#else
10485#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10486#endif
[email protected]23e482282013-06-14 16:08:0210487WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610488 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310489 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610490
10491 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710492 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10493 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610494 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10495 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610496
[email protected]8ddf8322012-02-23 18:08:0610497 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210498 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710499 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610500
[email protected]cdf8f7e72013-05-23 10:56:4610501 scoped_ptr<SpdyFrame> host1_req(
10502 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10503 scoped_ptr<SpdyFrame> host2_req(
10504 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610505 MockWrite spdy_writes[] = {
10506 CreateMockWrite(*host1_req, 1),
10507 CreateMockWrite(*host2_req, 4),
10508 };
[email protected]23e482282013-06-14 16:08:0210509 scoped_ptr<SpdyFrame> host1_resp(
10510 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10511 scoped_ptr<SpdyFrame> host1_resp_body(
10512 spdy_util_.ConstructSpdyBodyFrame(1, true));
10513 scoped_ptr<SpdyFrame> host2_resp(
10514 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10515 scoped_ptr<SpdyFrame> host2_resp_body(
10516 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610517 MockRead spdy_reads[] = {
10518 CreateMockRead(*host1_resp, 2),
10519 CreateMockRead(*host1_resp_body, 3),
10520 CreateMockRead(*host2_resp, 5),
10521 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610522 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610523 };
10524
[email protected]d2b5f092012-06-08 23:55:0210525 IPAddressNumber ip;
10526 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10527 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10528 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710529 OrderedSocketData spdy_data(
10530 connect,
10531 spdy_reads, arraysize(spdy_reads),
10532 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710533 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610534
[email protected]aa22b242011-11-16 18:58:2910535 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610536 HttpRequestInfo request1;
10537 request1.method = "GET";
10538 request1.url = GURL("https://www.google.com/");
10539 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010540 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610541
[email protected]49639fa2011-12-20 23:22:4110542 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610543 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110544 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610545
10546 const HttpResponseInfo* response = trans1.GetResponseInfo();
10547 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010548 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610549 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10550
10551 std::string response_data;
10552 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10553 EXPECT_EQ("hello!", response_data);
10554
10555 // Preload www.gmail.com into HostCache.
10556 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010557 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610558 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010559 rv = session_deps_.host_resolver->Resolve(resolve_info,
10560 DEFAULT_PRIORITY,
10561 &ignored,
10562 callback.callback(),
10563 NULL,
10564 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710565 EXPECT_EQ(ERR_IO_PENDING, rv);
10566 rv = callback.WaitForResult();
10567 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610568
10569 HttpRequestInfo request2;
10570 request2.method = "GET";
10571 request2.url = GURL("https://www.gmail.com/");
10572 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010573 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610574
[email protected]49639fa2011-12-20 23:22:4110575 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610576 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110577 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610578
10579 response = trans2.GetResponseInfo();
10580 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010581 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610582 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10583 EXPECT_TRUE(response->was_fetched_via_spdy);
10584 EXPECT_TRUE(response->was_npn_negotiated);
10585 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10586 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610587}
[email protected]45b170822012-05-04 21:18:1410588#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610589
[email protected]23e482282013-06-14 16:08:0210590TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210591 HttpStreamFactory::set_use_alternate_protocols(true);
10592 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10593
10594 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710595 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210597 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10598 pool_peer.DisableDomainAuthenticationVerification();
10599
10600 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210601 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710602 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210603
[email protected]cdf8f7e72013-05-23 10:56:4610604 scoped_ptr<SpdyFrame> host1_req(
10605 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10606 scoped_ptr<SpdyFrame> host2_req(
10607 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210608 MockWrite spdy_writes[] = {
10609 CreateMockWrite(*host1_req, 1),
10610 CreateMockWrite(*host2_req, 4),
10611 };
[email protected]23e482282013-06-14 16:08:0210612 scoped_ptr<SpdyFrame> host1_resp(
10613 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10614 scoped_ptr<SpdyFrame> host1_resp_body(
10615 spdy_util_.ConstructSpdyBodyFrame(1, true));
10616 scoped_ptr<SpdyFrame> host2_resp(
10617 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10618 scoped_ptr<SpdyFrame> host2_resp_body(
10619 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210620 MockRead spdy_reads[] = {
10621 CreateMockRead(*host1_resp, 2),
10622 CreateMockRead(*host1_resp_body, 3),
10623 CreateMockRead(*host2_resp, 5),
10624 CreateMockRead(*host2_resp_body, 6),
10625 MockRead(ASYNC, 0, 7),
10626 };
10627
10628 IPAddressNumber ip;
10629 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10630 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10631 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710632 OrderedSocketData spdy_data(
10633 connect,
10634 spdy_reads, arraysize(spdy_reads),
10635 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210637
10638 TestCompletionCallback callback;
10639 HttpRequestInfo request1;
10640 request1.method = "GET";
10641 request1.url = GURL("https://www.google.com/");
10642 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010643 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210644
10645 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10646 EXPECT_EQ(ERR_IO_PENDING, rv);
10647 EXPECT_EQ(OK, callback.WaitForResult());
10648
10649 const HttpResponseInfo* response = trans1.GetResponseInfo();
10650 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010651 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210652 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10653
10654 std::string response_data;
10655 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10656 EXPECT_EQ("hello!", response_data);
10657
10658 HttpRequestInfo request2;
10659 request2.method = "GET";
10660 request2.url = GURL("https://www.gmail.com/");
10661 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010662 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210663
10664 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10665 EXPECT_EQ(ERR_IO_PENDING, rv);
10666 EXPECT_EQ(OK, callback.WaitForResult());
10667
10668 response = trans2.GetResponseInfo();
10669 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010670 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210671 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10672 EXPECT_TRUE(response->was_fetched_via_spdy);
10673 EXPECT_TRUE(response->was_npn_negotiated);
10674 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10675 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210676}
10677
[email protected]e3ceb682011-06-28 23:55:4610678class OneTimeCachingHostResolver : public net::HostResolver {
10679 public:
10680 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10681 : host_port_(host_port) {}
10682 virtual ~OneTimeCachingHostResolver() {}
10683
10684 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10685
10686 // HostResolver methods:
10687 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010688 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610689 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910690 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610691 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010692 const BoundNetLog& net_log) OVERRIDE {
10693 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010694 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010695 }
10696
10697 virtual int ResolveFromCache(const RequestInfo& info,
10698 AddressList* addresses,
10699 const BoundNetLog& net_log) OVERRIDE {
10700 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10701 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910702 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610703 return rv;
10704 }
10705
[email protected]95a214c2011-08-04 21:50:4010706 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610707 host_resolver_.CancelRequest(req);
10708 }
10709
[email protected]46da33be2011-07-19 21:58:0410710 MockCachingHostResolver* GetMockHostResolver() {
10711 return &host_resolver_;
10712 }
10713
[email protected]e3ceb682011-06-28 23:55:4610714 private:
10715 MockCachingHostResolver host_resolver_;
10716 const HostPortPair host_port_;
10717};
10718
[email protected]45b170822012-05-04 21:18:1410719// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10720#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710721#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10722 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410723#else
[email protected]bb88e1d32013-05-03 23:11:0710724#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10725 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410726#endif
[email protected]23e482282013-06-14 16:08:0210727WRAPPED_TEST_P(HttpNetworkTransactionTest,
10728 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210729// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10730// prefix doesn't work with parametrized tests).
10731#if defined(OS_WIN)
10732 return;
10733#endif
10734
[email protected]e3ceb682011-06-28 23:55:4610735 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310736 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610737
10738 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610739 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410740 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710741 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610742 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710743 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610744 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10745 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610746
[email protected]8ddf8322012-02-23 18:08:0610747 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210748 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710749 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610750
[email protected]cdf8f7e72013-05-23 10:56:4610751 scoped_ptr<SpdyFrame> host1_req(
10752 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10753 scoped_ptr<SpdyFrame> host2_req(
10754 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610755 MockWrite spdy_writes[] = {
10756 CreateMockWrite(*host1_req, 1),
10757 CreateMockWrite(*host2_req, 4),
10758 };
[email protected]23e482282013-06-14 16:08:0210759 scoped_ptr<SpdyFrame> host1_resp(
10760 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10761 scoped_ptr<SpdyFrame> host1_resp_body(
10762 spdy_util_.ConstructSpdyBodyFrame(1, true));
10763 scoped_ptr<SpdyFrame> host2_resp(
10764 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10765 scoped_ptr<SpdyFrame> host2_resp_body(
10766 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610767 MockRead spdy_reads[] = {
10768 CreateMockRead(*host1_resp, 2),
10769 CreateMockRead(*host1_resp_body, 3),
10770 CreateMockRead(*host2_resp, 5),
10771 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610772 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610773 };
10774
[email protected]d2b5f092012-06-08 23:55:0210775 IPAddressNumber ip;
10776 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10777 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10778 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710779 OrderedSocketData spdy_data(
10780 connect,
10781 spdy_reads, arraysize(spdy_reads),
10782 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710783 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610784
[email protected]aa22b242011-11-16 18:58:2910785 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610786 HttpRequestInfo request1;
10787 request1.method = "GET";
10788 request1.url = GURL("https://www.google.com/");
10789 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010790 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610791
[email protected]49639fa2011-12-20 23:22:4110792 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610793 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110794 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610795
10796 const HttpResponseInfo* response = trans1.GetResponseInfo();
10797 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010798 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610799 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10800
10801 std::string response_data;
10802 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10803 EXPECT_EQ("hello!", response_data);
10804
10805 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1010806 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4610807 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010808 rv = host_resolver.Resolve(resolve_info,
10809 DEFAULT_PRIORITY,
10810 &ignored,
10811 callback.callback(),
10812 NULL,
10813 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710814 EXPECT_EQ(ERR_IO_PENDING, rv);
10815 rv = callback.WaitForResult();
10816 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610817
10818 HttpRequestInfo request2;
10819 request2.method = "GET";
10820 request2.url = GURL("https://www.gmail.com/");
10821 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010822 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610823
[email protected]49639fa2011-12-20 23:22:4110824 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610825 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110826 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610827
10828 response = trans2.GetResponseInfo();
10829 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010830 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610831 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10832 EXPECT_TRUE(response->was_fetched_via_spdy);
10833 EXPECT_TRUE(response->was_npn_negotiated);
10834 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10835 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610836}
[email protected]45b170822012-05-04 21:18:1410837#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4610838
[email protected]23e482282013-06-14 16:08:0210839TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910840 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610841 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910842 };
10843 MockRead data_reads2[] = {
10844 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10845 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610846 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910847 };
10848 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10849 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10850 StaticSocketDataProvider* data[] = { &data1, &data2 };
10851
10852 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10853
10854 EXPECT_EQ(OK, out.rv);
10855 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10856 EXPECT_EQ("hello world", out.response_data);
10857}
10858
[email protected]23e482282013-06-14 16:08:0210859TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910860 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0610861 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910862 };
10863 MockWrite data_writes2[] = {
10864 MockWrite("GET / HTTP/1.1\r\n"
10865 "Host: www.google.com\r\n"
10866 "Connection: keep-alive\r\n\r\n"),
10867 };
10868 MockRead data_reads2[] = {
10869 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10870 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610871 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910872 };
10873 StaticSocketDataProvider data1(NULL, 0,
10874 data_writes1, arraysize(data_writes1));
10875 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10876 data_writes2, arraysize(data_writes2));
10877 StaticSocketDataProvider* data[] = { &data1, &data2 };
10878
10879 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10880
10881 EXPECT_EQ(OK, out.rv);
10882 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10883 EXPECT_EQ("hello world", out.response_data);
10884}
10885
[email protected]23e482282013-06-14 16:08:0210886TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0410887 const std::string https_url = "https://www.google.com/";
10888 const std::string http_url = "http://www.google.com:443/";
10889
10890 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4610891 scoped_ptr<SpdyFrame> req1(
10892 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410893
10894 MockWrite writes1[] = {
10895 CreateMockWrite(*req1, 0),
10896 };
10897
[email protected]23e482282013-06-14 16:08:0210898 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10899 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0410900 MockRead reads1[] = {
10901 CreateMockRead(*resp1, 1),
10902 CreateMockRead(*body1, 2),
10903 MockRead(ASYNC, ERR_IO_PENDING, 3)
10904 };
10905
[email protected]dd54bd82012-07-19 23:44:5710906 DelayedSocketData data1(
10907 1, reads1, arraysize(reads1),
10908 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410909 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710910 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410911
10912 // HTTP GET for the HTTP URL
10913 MockWrite writes2[] = {
10914 MockWrite(ASYNC, 4,
10915 "GET / HTTP/1.1\r\n"
10916 "Host: www.google.com:443\r\n"
10917 "Connection: keep-alive\r\n\r\n"),
10918 };
10919
10920 MockRead reads2[] = {
10921 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10922 MockRead(ASYNC, 6, "hello"),
10923 MockRead(ASYNC, 7, OK),
10924 };
10925
[email protected]dd54bd82012-07-19 23:44:5710926 DelayedSocketData data2(
10927 1, reads2, arraysize(reads2),
10928 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0410929
[email protected]8450d722012-07-02 19:14:0410930 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210931 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710932 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10933 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10934 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0410935
[email protected]bb88e1d32013-05-03 23:11:0710936 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410937
10938 // Start the first transaction to set up the SpdySession
10939 HttpRequestInfo request1;
10940 request1.method = "GET";
10941 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410942 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010943 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410944 TestCompletionCallback callback1;
10945 EXPECT_EQ(ERR_IO_PENDING,
10946 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410947 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410948
10949 EXPECT_EQ(OK, callback1.WaitForResult());
10950 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
10951
10952 // Now, start the HTTP request
10953 HttpRequestInfo request2;
10954 request2.method = "GET";
10955 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0410956 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010957 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0410958 TestCompletionCallback callback2;
10959 EXPECT_EQ(ERR_IO_PENDING,
10960 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410961 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410962
10963 EXPECT_EQ(OK, callback2.WaitForResult());
10964 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
10965}
10966
[email protected]23e482282013-06-14 16:08:0210967TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0410968 const std::string https_url = "https://www.google.com/";
10969 const std::string http_url = "http://www.google.com:443/";
10970
10971 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5410972 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
10973 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4610974 scoped_ptr<SpdyFrame> req1(
10975 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410976
10977 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0210978 scoped_ptr<SpdyFrame> wrapped_req1(
10979 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0410980 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0210981 spdy_util_.GetMethodKey(), "GET",
10982 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
10983 spdy_util_.GetHostKey(), "www.google.com:443",
10984 spdy_util_.GetSchemeKey(), "http",
10985 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0410986 };
[email protected]4bd46222013-05-14 19:32:2310987 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
10988 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
10989 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0410990
10991 MockWrite writes1[] = {
10992 CreateMockWrite(*connect, 0),
10993 CreateMockWrite(*wrapped_req1, 2),
10994 CreateMockWrite(*req2, 5),
10995 };
10996
[email protected]23e482282013-06-14 16:08:0210997 scoped_ptr<SpdyFrame> conn_resp(
10998 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10999 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11000 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11001 scoped_ptr<SpdyFrame> wrapped_resp1(
11002 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11003 scoped_ptr<SpdyFrame> wrapped_body1(
11004 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11005 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11006 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411007 MockRead reads1[] = {
11008 CreateMockRead(*conn_resp, 1),
11009 CreateMockRead(*wrapped_resp1, 3),
11010 CreateMockRead(*wrapped_body1, 4),
11011 CreateMockRead(*resp2, 6),
11012 CreateMockRead(*body2, 7),
11013 MockRead(ASYNC, ERR_IO_PENDING, 8)
11014 };
11015
[email protected]dd54bd82012-07-19 23:44:5711016 DeterministicSocketData data1(reads1, arraysize(reads1),
11017 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411018 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711019 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411020
[email protected]bb88e1d32013-05-03 23:11:0711021 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211022 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11023 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711024 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411025 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211026 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711027 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411028 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211029 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711030 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11031 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411032
11033 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711034 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411035
11036 // Start the first transaction to set up the SpdySession
11037 HttpRequestInfo request1;
11038 request1.method = "GET";
11039 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411040 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011041 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411042 TestCompletionCallback callback1;
11043 EXPECT_EQ(ERR_IO_PENDING,
11044 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411045 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711046 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411047
11048 EXPECT_EQ(OK, callback1.WaitForResult());
11049 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11050
[email protected]f6c63db52013-02-02 00:35:2211051 LoadTimingInfo load_timing_info1;
11052 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11053 TestLoadTimingNotReusedWithPac(load_timing_info1,
11054 CONNECT_TIMING_HAS_SSL_TIMES);
11055
[email protected]8450d722012-07-02 19:14:0411056 // Now, start the HTTP request
11057 HttpRequestInfo request2;
11058 request2.method = "GET";
11059 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411060 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011061 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411062 TestCompletionCallback callback2;
11063 EXPECT_EQ(ERR_IO_PENDING,
11064 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411065 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711066 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411067
11068 EXPECT_EQ(OK, callback2.WaitForResult());
11069 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211070
11071 LoadTimingInfo load_timing_info2;
11072 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11073 // The established SPDY sessions is considered reused by the HTTP request.
11074 TestLoadTimingReusedWithPac(load_timing_info2);
11075 // HTTP requests over a SPDY session should have a different connection
11076 // socket_log_id than requests over a tunnel.
11077 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411078}
11079
[email protected]23e482282013-06-14 16:08:0211080TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411081 HttpStreamFactory::set_force_spdy_always(true);
11082 const std::string https_url = "https://www.google.com/";
11083 const std::string http_url = "http://www.google.com:443/";
11084
11085 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611086 scoped_ptr<SpdyFrame> req1(
11087 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411088 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611089 scoped_ptr<SpdyFrame> req2(
11090 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411091
11092 MockWrite writes[] = {
11093 CreateMockWrite(*req1, 1),
11094 CreateMockWrite(*req2, 4),
11095 };
11096
[email protected]23e482282013-06-14 16:08:0211097 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11098 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11099 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11100 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411101 MockRead reads[] = {
11102 CreateMockRead(*resp1, 2),
11103 CreateMockRead(*body1, 3),
11104 CreateMockRead(*resp2, 5),
11105 CreateMockRead(*body2, 6),
11106 MockRead(ASYNC, ERR_IO_PENDING, 7)
11107 };
11108
[email protected]dd54bd82012-07-19 23:44:5711109 OrderedSocketData data(reads, arraysize(reads),
11110 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411111
[email protected]8450d722012-07-02 19:14:0411112 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211113 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11115 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411116
[email protected]bb88e1d32013-05-03 23:11:0711117 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411118
11119 // Start the first transaction to set up the SpdySession
11120 HttpRequestInfo request1;
11121 request1.method = "GET";
11122 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411123 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011124 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411125 TestCompletionCallback callback1;
11126 EXPECT_EQ(ERR_IO_PENDING,
11127 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411128 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411129
11130 EXPECT_EQ(OK, callback1.WaitForResult());
11131 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11132
11133 // Now, start the HTTP request
11134 HttpRequestInfo request2;
11135 request2.method = "GET";
11136 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411137 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011138 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411139 TestCompletionCallback callback2;
11140 EXPECT_EQ(ERR_IO_PENDING,
11141 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411142 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411143
11144 EXPECT_EQ(OK, callback2.WaitForResult());
11145 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11146}
11147
[email protected]2d88e7d2012-07-19 17:55:1711148// Test that in the case where we have a SPDY session to a SPDY proxy
11149// that we do not pool other origins that resolve to the same IP when
11150// the certificate does not match the new origin.
11151// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211152TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711153 const std::string url1 = "http://www.google.com/";
11154 const std::string url2 = "https://mail.google.com/";
11155 const std::string ip_addr = "1.2.3.4";
11156
11157 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211158 scoped_ptr<SpdyHeaderBlock> headers(
11159 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311160 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211161 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711162
11163 MockWrite writes1[] = {
11164 CreateMockWrite(*req1, 0),
11165 };
11166
[email protected]23e482282013-06-14 16:08:0211167 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11168 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711169 MockRead reads1[] = {
11170 CreateMockRead(*resp1, 1),
11171 CreateMockRead(*body1, 2),
11172 MockRead(ASYNC, OK, 3) // EOF
11173 };
11174
11175 scoped_ptr<DeterministicSocketData> data1(
11176 new DeterministicSocketData(reads1, arraysize(reads1),
11177 writes1, arraysize(writes1)));
11178 IPAddressNumber ip;
11179 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11180 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11181 MockConnect connect_data1(ASYNC, OK, peer_addr);
11182 data1->set_connect_data(connect_data1);
11183
11184 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611185 scoped_ptr<SpdyFrame> req2(
11186 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711187
11188 MockWrite writes2[] = {
11189 CreateMockWrite(*req2, 0),
11190 };
11191
[email protected]23e482282013-06-14 16:08:0211192 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11193 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711194 MockRead reads2[] = {
11195 CreateMockRead(*resp2, 1),
11196 CreateMockRead(*body2, 2),
11197 MockRead(ASYNC, OK, 3) // EOF
11198 };
11199
11200 scoped_ptr<DeterministicSocketData> data2(
11201 new DeterministicSocketData(reads2, arraysize(reads2),
11202 writes2, arraysize(writes2)));
11203 MockConnect connect_data2(ASYNC, OK);
11204 data2->set_connect_data(connect_data2);
11205
11206 // Set up a proxy config that sends HTTP requests to a proxy, and
11207 // all others direct.
11208 ProxyConfig proxy_config;
11209 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11210 CapturingProxyResolver* capturing_proxy_resolver =
11211 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711212 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711213 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11214 NULL));
11215
11216 // Load a valid cert. Note, that this does not need to
11217 // be valid for proxy because the MockSSLClientSocket does
11218 // not actually verify it. But SpdySession will use this
11219 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511220 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711221 scoped_refptr<X509Certificate> server_cert(
11222 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11223 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11224
11225 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211226 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711227 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711228 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11229 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11230 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711231
11232 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211233 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711234 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11235 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11236 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711237
[email protected]bb88e1d32013-05-03 23:11:0711238 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11239 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11240 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711241
11242 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711243 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711244
11245 // Start the first transaction to set up the SpdySession
11246 HttpRequestInfo request1;
11247 request1.method = "GET";
11248 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711249 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011250 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711251 TestCompletionCallback callback1;
11252 ASSERT_EQ(ERR_IO_PENDING,
11253 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11254 data1->RunFor(3);
11255
11256 ASSERT_TRUE(callback1.have_result());
11257 EXPECT_EQ(OK, callback1.WaitForResult());
11258 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11259
11260 // Now, start the HTTP request
11261 HttpRequestInfo request2;
11262 request2.method = "GET";
11263 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711264 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011265 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711266 TestCompletionCallback callback2;
11267 EXPECT_EQ(ERR_IO_PENDING,
11268 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411269 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711270 data2->RunFor(3);
11271
11272 ASSERT_TRUE(callback2.have_result());
11273 EXPECT_EQ(OK, callback2.WaitForResult());
11274 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11275}
11276
[email protected]85f97342013-04-17 06:12:2411277// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11278// error) in SPDY session, removes the socket from pool and closes the SPDY
11279// session. Verify that new url's from the same HttpNetworkSession (and a new
11280// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211281TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411282 const std::string https_url = "https://www.google.com/";
11283
11284 MockRead reads1[] = {
11285 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11286 };
11287
11288 scoped_ptr<DeterministicSocketData> data1(
11289 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11290 data1->SetStop(1);
11291
[email protected]cdf8f7e72013-05-23 10:56:4611292 scoped_ptr<SpdyFrame> req2(
11293 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411294 MockWrite writes2[] = {
11295 CreateMockWrite(*req2, 0),
11296 };
11297
[email protected]23e482282013-06-14 16:08:0211298 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11299 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411300 MockRead reads2[] = {
11301 CreateMockRead(*resp2, 1),
11302 CreateMockRead(*body2, 2),
11303 MockRead(ASYNC, OK, 3) // EOF
11304 };
11305
11306 scoped_ptr<DeterministicSocketData> data2(
11307 new DeterministicSocketData(reads2, arraysize(reads2),
11308 writes2, arraysize(writes2)));
11309
[email protected]85f97342013-04-17 06:12:2411310 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211311 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711312 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11313 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11314 data1.get());
[email protected]85f97342013-04-17 06:12:2411315
11316 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211317 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711318 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11319 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11320 data2.get());
[email protected]85f97342013-04-17 06:12:2411321
11322 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711323 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411324
11325 // Start the first transaction to set up the SpdySession and verify that
11326 // connection was closed.
11327 HttpRequestInfo request1;
11328 request1.method = "GET";
11329 request1.url = GURL(https_url);
11330 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011331 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411332 TestCompletionCallback callback1;
11333 EXPECT_EQ(ERR_IO_PENDING,
11334 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411335 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411336 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11337
11338 // Now, start the second request and make sure it succeeds.
11339 HttpRequestInfo request2;
11340 request2.method = "GET";
11341 request2.url = GURL(https_url);
11342 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011343 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411344 TestCompletionCallback callback2;
11345 EXPECT_EQ(ERR_IO_PENDING,
11346 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411347 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411348 data2->RunFor(3);
11349
11350 ASSERT_TRUE(callback2.have_result());
11351 EXPECT_EQ(OK, callback2.WaitForResult());
11352 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11353}
11354
[email protected]23e482282013-06-14 16:08:0211355TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311356 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11357 ClientSocketPoolManager::set_max_sockets_per_group(
11358 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11359 ClientSocketPoolManager::set_max_sockets_per_pool(
11360 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11361
11362 // Use two different hosts with different IPs so they don't get pooled.
11363 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11364 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11365 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11366
11367 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211368 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311369 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211370 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11373
[email protected]cdf8f7e72013-05-23 10:56:4611374 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311375 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11376 MockWrite spdy1_writes[] = {
11377 CreateMockWrite(*host1_req, 1),
11378 };
[email protected]23e482282013-06-14 16:08:0211379 scoped_ptr<SpdyFrame> host1_resp(
11380 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11381 scoped_ptr<SpdyFrame> host1_resp_body(
11382 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311383 MockRead spdy1_reads[] = {
11384 CreateMockRead(*host1_resp, 2),
11385 CreateMockRead(*host1_resp_body, 3),
11386 MockRead(ASYNC, ERR_IO_PENDING, 4),
11387 };
11388
11389 scoped_ptr<OrderedSocketData> spdy1_data(
11390 new OrderedSocketData(
11391 spdy1_reads, arraysize(spdy1_reads),
11392 spdy1_writes, arraysize(spdy1_writes)));
11393 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11394
[email protected]cdf8f7e72013-05-23 10:56:4611395 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311396 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11397 MockWrite spdy2_writes[] = {
11398 CreateMockWrite(*host2_req, 1),
11399 };
[email protected]23e482282013-06-14 16:08:0211400 scoped_ptr<SpdyFrame> host2_resp(
11401 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11402 scoped_ptr<SpdyFrame> host2_resp_body(
11403 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311404 MockRead spdy2_reads[] = {
11405 CreateMockRead(*host2_resp, 2),
11406 CreateMockRead(*host2_resp_body, 3),
11407 MockRead(ASYNC, ERR_IO_PENDING, 4),
11408 };
11409
11410 scoped_ptr<OrderedSocketData> spdy2_data(
11411 new OrderedSocketData(
11412 spdy2_reads, arraysize(spdy2_reads),
11413 spdy2_writes, arraysize(spdy2_writes)));
11414 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11415
11416 MockWrite http_write[] = {
11417 MockWrite("GET / HTTP/1.1\r\n"
11418 "Host: www.a.com\r\n"
11419 "Connection: keep-alive\r\n\r\n"),
11420 };
11421
11422 MockRead http_read[] = {
11423 MockRead("HTTP/1.1 200 OK\r\n"),
11424 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11425 MockRead("Content-Length: 6\r\n\r\n"),
11426 MockRead("hello!"),
11427 };
11428 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11429 http_write, arraysize(http_write));
11430 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11431
11432 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011433 SpdySessionKey spdy_session_key_a(
11434 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311435 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611436 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311437
11438 TestCompletionCallback callback;
11439 HttpRequestInfo request1;
11440 request1.method = "GET";
11441 request1.url = GURL("https://www.a.com/");
11442 request1.load_flags = 0;
11443 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311445
11446 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11447 EXPECT_EQ(ERR_IO_PENDING, rv);
11448 EXPECT_EQ(OK, callback.WaitForResult());
11449
11450 const HttpResponseInfo* response = trans->GetResponseInfo();
11451 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011452 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311453 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11454 EXPECT_TRUE(response->was_fetched_via_spdy);
11455 EXPECT_TRUE(response->was_npn_negotiated);
11456
11457 std::string response_data;
11458 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11459 EXPECT_EQ("hello!", response_data);
11460 trans.reset();
11461 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611462 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311463
11464 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011465 SpdySessionKey spdy_session_key_b(
11466 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311467 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611468 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311469 HttpRequestInfo request2;
11470 request2.method = "GET";
11471 request2.url = GURL("https://www.b.com/");
11472 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011473 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311474
11475 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11476 EXPECT_EQ(ERR_IO_PENDING, rv);
11477 EXPECT_EQ(OK, callback.WaitForResult());
11478
11479 response = trans->GetResponseInfo();
11480 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011481 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311482 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11483 EXPECT_TRUE(response->was_fetched_via_spdy);
11484 EXPECT_TRUE(response->was_npn_negotiated);
11485 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11486 EXPECT_EQ("hello!", response_data);
11487 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611488 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311489 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611490 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311491
11492 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011493 SpdySessionKey spdy_session_key_a1(
11494 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311495 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611496 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311497 HttpRequestInfo request3;
11498 request3.method = "GET";
11499 request3.url = GURL("http://www.a.com/");
11500 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011501 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311502
11503 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11504 EXPECT_EQ(ERR_IO_PENDING, rv);
11505 EXPECT_EQ(OK, callback.WaitForResult());
11506
11507 response = trans->GetResponseInfo();
11508 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011509 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311510 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11511 EXPECT_FALSE(response->was_fetched_via_spdy);
11512 EXPECT_FALSE(response->was_npn_negotiated);
11513 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11514 EXPECT_EQ("hello!", response_data);
11515 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611516 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311517 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611518 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311519}
11520
[email protected]79e1fd62013-06-20 06:50:0411521TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11522 HttpRequestInfo request;
11523 request.method = "GET";
11524 request.url = GURL("http://www.google.com/");
11525 request.load_flags = 0;
11526
11527 scoped_ptr<HttpTransaction> trans(
11528 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11529 CreateSession(&session_deps_)));
11530
11531 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11532 StaticSocketDataProvider data;
11533 data.set_connect_data(mock_connect);
11534 session_deps_.socket_factory->AddSocketDataProvider(&data);
11535
11536 TestCompletionCallback callback;
11537
11538 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11539 EXPECT_EQ(ERR_IO_PENDING, rv);
11540
11541 rv = callback.WaitForResult();
11542 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11543
11544 EXPECT_EQ(NULL, trans->GetResponseInfo());
11545
11546 // We don't care whether this succeeds or fails, but it shouldn't crash.
11547 HttpRequestHeaders request_headers;
11548 trans->GetFullRequestHeaders(&request_headers);
11549}
11550
11551TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11552 HttpRequestInfo request;
11553 request.method = "GET";
11554 request.url = GURL("http://www.google.com/");
11555 request.load_flags = 0;
11556
11557 scoped_ptr<HttpTransaction> trans(
11558 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11559 CreateSession(&session_deps_)));
11560
11561 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11562 StaticSocketDataProvider data;
11563 data.set_connect_data(mock_connect);
11564 session_deps_.socket_factory->AddSocketDataProvider(&data);
11565
11566 TestCompletionCallback callback;
11567
11568 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11569 EXPECT_EQ(ERR_IO_PENDING, rv);
11570
11571 rv = callback.WaitForResult();
11572 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11573
11574 EXPECT_EQ(NULL, trans->GetResponseInfo());
11575
11576 // We don't care whether this succeeds or fails, but it shouldn't crash.
11577 HttpRequestHeaders request_headers;
11578 trans->GetFullRequestHeaders(&request_headers);
11579}
11580
11581TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11582 HttpRequestInfo request;
11583 request.method = "GET";
11584 request.url = GURL("http://www.google.com/");
11585 request.load_flags = 0;
11586
11587 scoped_ptr<HttpTransaction> trans(
11588 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11589 CreateSession(&session_deps_)));
11590
11591 MockWrite data_writes[] = {
11592 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11593 };
11594 MockRead data_reads[] = {
11595 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11596 };
11597
11598 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11599 data_writes, arraysize(data_writes));
11600 session_deps_.socket_factory->AddSocketDataProvider(&data);
11601
11602 TestCompletionCallback callback;
11603
11604 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11605 EXPECT_EQ(ERR_IO_PENDING, rv);
11606
11607 rv = callback.WaitForResult();
11608 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11609
11610 EXPECT_EQ(NULL, trans->GetResponseInfo());
11611
11612 HttpRequestHeaders request_headers;
11613 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11614 EXPECT_TRUE(request_headers.HasHeader("Host"));
11615}
11616
11617TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11618 HttpRequestInfo request;
11619 request.method = "GET";
11620 request.url = GURL("http://www.google.com/");
11621 request.load_flags = 0;
11622
11623 scoped_ptr<HttpTransaction> trans(
11624 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11625 CreateSession(&session_deps_)));
11626
11627 MockWrite data_writes[] = {
11628 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11629 };
11630 MockRead data_reads[] = {
11631 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11632 };
11633
11634 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11635 data_writes, arraysize(data_writes));
11636 session_deps_.socket_factory->AddSocketDataProvider(&data);
11637
11638 TestCompletionCallback callback;
11639
11640 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11641 EXPECT_EQ(ERR_IO_PENDING, rv);
11642
11643 rv = callback.WaitForResult();
11644 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11645
11646 EXPECT_EQ(NULL, trans->GetResponseInfo());
11647
11648 HttpRequestHeaders request_headers;
11649 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11650 EXPECT_TRUE(request_headers.HasHeader("Host"));
11651}
11652
11653TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11654 HttpRequestInfo request;
11655 request.method = "GET";
11656 request.url = GURL("http://www.google.com/");
11657 request.load_flags = 0;
11658
11659 scoped_ptr<HttpTransaction> trans(
11660 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11661 CreateSession(&session_deps_)));
11662
11663 MockWrite data_writes[] = {
11664 MockWrite("GET / HTTP/1.1\r\n"
11665 "Host: www.google.com\r\n"
11666 "Connection: keep-alive\r\n\r\n"),
11667 };
11668 MockRead data_reads[] = {
11669 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11670 };
11671
11672 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11673 data_writes, arraysize(data_writes));
11674 session_deps_.socket_factory->AddSocketDataProvider(&data);
11675
11676 TestCompletionCallback callback;
11677
11678 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11679 EXPECT_EQ(ERR_IO_PENDING, rv);
11680
11681 rv = callback.WaitForResult();
11682 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11683
11684 EXPECT_EQ(NULL, trans->GetResponseInfo());
11685
11686 HttpRequestHeaders request_headers;
11687 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11688 EXPECT_TRUE(request_headers.HasHeader("Host"));
11689}
11690
11691TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11692 HttpRequestInfo request;
11693 request.method = "GET";
11694 request.url = GURL("http://www.google.com/");
11695 request.load_flags = 0;
11696
11697 scoped_ptr<HttpTransaction> trans(
11698 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11699 CreateSession(&session_deps_)));
11700
11701 MockWrite data_writes[] = {
11702 MockWrite("GET / HTTP/1.1\r\n"
11703 "Host: www.google.com\r\n"
11704 "Connection: keep-alive\r\n\r\n"),
11705 };
11706 MockRead data_reads[] = {
11707 MockRead(ASYNC, ERR_CONNECTION_RESET),
11708 };
11709
11710 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11711 data_writes, arraysize(data_writes));
11712 session_deps_.socket_factory->AddSocketDataProvider(&data);
11713
11714 TestCompletionCallback callback;
11715
11716 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11717 EXPECT_EQ(ERR_IO_PENDING, rv);
11718
11719 rv = callback.WaitForResult();
11720 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11721
11722 EXPECT_EQ(NULL, trans->GetResponseInfo());
11723
11724 HttpRequestHeaders request_headers;
11725 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11726 EXPECT_TRUE(request_headers.HasHeader("Host"));
11727}
11728
11729TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11730 HttpRequestInfo request;
11731 request.method = "GET";
11732 request.url = GURL("http://www.google.com/");
11733 request.load_flags = 0;
11734 request.extra_headers.SetHeader("X-Foo", "bar");
11735
11736 scoped_ptr<HttpTransaction> trans(
11737 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11738 CreateSession(&session_deps_)));
11739
11740 MockWrite data_writes[] = {
11741 MockWrite("GET / HTTP/1.1\r\n"
11742 "Host: www.google.com\r\n"
11743 "Connection: keep-alive\r\n"
11744 "X-Foo: bar\r\n\r\n"),
11745 };
11746 MockRead data_reads[] = {
11747 MockRead("HTTP/1.1 200 OK\r\n"
11748 "Content-Length: 5\r\n\r\n"
11749 "hello"),
11750 MockRead(ASYNC, ERR_UNEXPECTED),
11751 };
11752
11753 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11754 data_writes, arraysize(data_writes));
11755 session_deps_.socket_factory->AddSocketDataProvider(&data);
11756
11757 TestCompletionCallback callback;
11758
11759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11760 EXPECT_EQ(ERR_IO_PENDING, rv);
11761
11762 rv = callback.WaitForResult();
11763 EXPECT_EQ(OK, rv);
11764
11765 HttpRequestHeaders request_headers;
11766 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11767 std::string foo;
11768 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11769 EXPECT_EQ("bar", foo);
11770}
11771
[email protected]bf828982013-08-14 18:01:4711772namespace {
11773
[email protected]e86839fd2013-08-14 18:29:0311774// Fake HttpStreamBase that simply records calls to SetPriority().
11775class FakeStream : public HttpStreamBase,
11776 public base::SupportsWeakPtr<FakeStream> {
11777 public:
11778 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
11779 virtual ~FakeStream() {}
11780
11781 RequestPriority priority() const { return priority_; }
11782
11783 virtual int InitializeStream(const HttpRequestInfo* request_info,
11784 RequestPriority priority,
11785 const BoundNetLog& net_log,
11786 const CompletionCallback& callback) OVERRIDE {
11787 return ERR_IO_PENDING;
11788 }
11789
11790 virtual int SendRequest(const HttpRequestHeaders& request_headers,
11791 HttpResponseInfo* response,
11792 const CompletionCallback& callback) OVERRIDE {
11793 ADD_FAILURE();
11794 return ERR_UNEXPECTED;
11795 }
11796
11797 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
11798 ADD_FAILURE();
11799 return ERR_UNEXPECTED;
11800 }
11801
11802 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
11803 ADD_FAILURE();
11804 return NULL;
11805 }
11806
11807 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
11808 const CompletionCallback& callback) OVERRIDE {
11809 ADD_FAILURE();
11810 return ERR_UNEXPECTED;
11811 }
11812
11813 virtual void Close(bool not_reusable) OVERRIDE {}
11814
11815 virtual bool IsResponseBodyComplete() const OVERRIDE {
11816 ADD_FAILURE();
11817 return false;
11818 }
11819
11820 virtual bool CanFindEndOfResponse() const OVERRIDE {
11821 return false;
11822 }
11823
11824 virtual bool IsConnectionReused() const OVERRIDE {
11825 ADD_FAILURE();
11826 return false;
11827 }
11828
11829 virtual void SetConnectionReused() OVERRIDE {
11830 ADD_FAILURE();
11831 }
11832
11833 virtual bool IsConnectionReusable() const OVERRIDE {
11834 ADD_FAILURE();
11835 return false;
11836 }
11837
11838 virtual bool GetLoadTimingInfo(
11839 LoadTimingInfo* load_timing_info) const OVERRIDE {
11840 ADD_FAILURE();
11841 return false;
11842 }
11843
11844 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
11845 ADD_FAILURE();
11846 }
11847
11848 virtual void GetSSLCertRequestInfo(
11849 SSLCertRequestInfo* cert_request_info) OVERRIDE {
11850 ADD_FAILURE();
11851 }
11852
11853 virtual bool IsSpdyHttpStream() const OVERRIDE {
11854 ADD_FAILURE();
11855 return false;
11856 }
11857
11858 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
11859 ADD_FAILURE();
11860 }
11861
11862 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11863 priority_ = priority;
11864 }
11865
11866 private:
11867 RequestPriority priority_;
11868
11869 DISALLOW_COPY_AND_ASSIGN(FakeStream);
11870};
11871
11872// Fake HttpStreamRequest that simply records calls to SetPriority()
11873// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4711874class FakeStreamRequest : public HttpStreamRequest,
11875 public base::SupportsWeakPtr<FakeStreamRequest> {
11876 public:
[email protected]e86839fd2013-08-14 18:29:0311877 FakeStreamRequest(RequestPriority priority,
11878 HttpStreamRequest::Delegate* delegate)
11879 : priority_(priority),
11880 delegate_(delegate) {}
11881
[email protected]bf828982013-08-14 18:01:4711882 virtual ~FakeStreamRequest() {}
11883
11884 RequestPriority priority() const { return priority_; }
11885
[email protected]e86839fd2013-08-14 18:29:0311886 // Create a new FakeStream and pass it to the request's
11887 // delegate. Returns a weak pointer to the FakeStream.
11888 base::WeakPtr<FakeStream> FinishStreamRequest() {
11889 FakeStream* fake_stream = new FakeStream(priority_);
11890 // Do this before calling OnStreamReady() as OnStreamReady() may
11891 // immediately delete |fake_stream|.
11892 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
11893 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
11894 return weak_stream;
11895 }
11896
[email protected]bf828982013-08-14 18:01:4711897 virtual int RestartTunnelWithProxyAuth(
11898 const AuthCredentials& credentials) OVERRIDE {
11899 ADD_FAILURE();
11900 return ERR_UNEXPECTED;
11901 }
11902
11903 virtual LoadState GetLoadState() const OVERRIDE {
11904 ADD_FAILURE();
11905 return LoadState();
11906 }
11907
11908 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11909 priority_ = priority;
11910 }
11911
11912 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711913 return false;
11914 }
11915
11916 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711917 return kProtoUnknown;
11918 }
11919
11920 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711921 return false;
11922 }
11923
11924 private:
11925 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0311926 HttpStreamRequest::Delegate* const delegate_;
[email protected]bf828982013-08-14 18:01:4711927
11928 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
11929};
11930
11931// Fake HttpStreamFactory that vends FakeStreamRequests.
11932class FakeStreamFactory : public HttpStreamFactory {
11933 public:
11934 FakeStreamFactory() {}
11935 virtual ~FakeStreamFactory() {}
11936
11937 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
11938 // RequestStream() (which may be NULL if it was destroyed already).
11939 base::WeakPtr<FakeStreamRequest> last_stream_request() {
11940 return last_stream_request_;
11941 }
11942
11943 virtual HttpStreamRequest* RequestStream(
11944 const HttpRequestInfo& info,
11945 RequestPriority priority,
11946 const SSLConfig& server_ssl_config,
11947 const SSLConfig& proxy_ssl_config,
11948 HttpStreamRequest::Delegate* delegate,
11949 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0311950 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4711951 last_stream_request_ = fake_request->AsWeakPtr();
11952 return fake_request;
11953 }
11954
11955 virtual HttpStreamRequest* RequestWebSocketStream(
11956 const HttpRequestInfo& info,
11957 RequestPriority priority,
11958 const SSLConfig& server_ssl_config,
11959 const SSLConfig& proxy_ssl_config,
11960 HttpStreamRequest::Delegate* delegate,
11961 WebSocketStreamBase::Factory* factory,
11962 const BoundNetLog& net_log) OVERRIDE {
11963 ADD_FAILURE();
11964 return NULL;
11965 }
11966
11967 virtual void PreconnectStreams(int num_streams,
11968 const HttpRequestInfo& info,
11969 RequestPriority priority,
11970 const SSLConfig& server_ssl_config,
11971 const SSLConfig& proxy_ssl_config) OVERRIDE {
11972 ADD_FAILURE();
11973 }
11974
11975 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
11976 ADD_FAILURE();
11977 return NULL;
11978 }
11979
11980 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
11981 ADD_FAILURE();
11982 return NULL;
11983 }
11984
11985 private:
11986 base::WeakPtr<FakeStreamRequest> last_stream_request_;
11987
11988 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
11989};
11990
11991} // namespace
11992
11993// Make sure that HttpNetworkTransaction passes on its priority to its
11994// stream request on start.
11995TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
11996 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11997 HttpNetworkSessionPeer peer(session);
11998 FakeStreamFactory* fake_factory = new FakeStreamFactory();
11999 peer.SetHttpStreamFactory(fake_factory);
12000
12001 HttpNetworkTransaction trans(LOW, session);
12002
12003 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12004
12005 HttpRequestInfo request;
12006 TestCompletionCallback callback;
12007 EXPECT_EQ(ERR_IO_PENDING,
12008 trans.Start(&request, callback.callback(), BoundNetLog()));
12009
12010 base::WeakPtr<FakeStreamRequest> fake_request =
12011 fake_factory->last_stream_request();
12012 ASSERT_TRUE(fake_request != NULL);
12013 EXPECT_EQ(LOW, fake_request->priority());
12014}
12015
12016// Make sure that HttpNetworkTransaction passes on its priority
12017// updates to its stream request.
12018TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12019 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12020 HttpNetworkSessionPeer peer(session);
12021 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12022 peer.SetHttpStreamFactory(fake_factory);
12023
12024 HttpNetworkTransaction trans(LOW, session);
12025
12026 HttpRequestInfo request;
12027 TestCompletionCallback callback;
12028 EXPECT_EQ(ERR_IO_PENDING,
12029 trans.Start(&request, callback.callback(), BoundNetLog()));
12030
12031 base::WeakPtr<FakeStreamRequest> fake_request =
12032 fake_factory->last_stream_request();
12033 ASSERT_TRUE(fake_request != NULL);
12034 EXPECT_EQ(LOW, fake_request->priority());
12035
12036 trans.SetPriority(LOWEST);
12037 ASSERT_TRUE(fake_request != NULL);
12038 EXPECT_EQ(LOWEST, fake_request->priority());
12039}
12040
[email protected]e86839fd2013-08-14 18:29:0312041// Make sure that HttpNetworkTransaction passes on its priority
12042// updates to its stream.
12043TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12044 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12045 HttpNetworkSessionPeer peer(session);
12046 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12047 peer.SetHttpStreamFactory(fake_factory);
12048
12049 HttpNetworkTransaction trans(LOW, session);
12050
12051 HttpRequestInfo request;
12052 TestCompletionCallback callback;
12053 EXPECT_EQ(ERR_IO_PENDING,
12054 trans.Start(&request, callback.callback(), BoundNetLog()));
12055
12056 base::WeakPtr<FakeStreamRequest> fake_request =
12057 fake_factory->last_stream_request();
12058 ASSERT_TRUE(fake_request != NULL);
12059 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12060 ASSERT_TRUE(fake_stream != NULL);
12061 EXPECT_EQ(LOW, fake_stream->priority());
12062
12063 trans.SetPriority(LOWEST);
12064 EXPECT_EQ(LOWEST, fake_stream->priority());
12065}
12066
[email protected]043b68c82013-08-22 23:41:5212067// Tests that when a used socket is returned to the SSL socket pool, it's closed
12068// if the transport socket pool is stalled on the global socket limit.
12069TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12070 ClientSocketPoolManager::set_max_sockets_per_group(
12071 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12072 ClientSocketPoolManager::set_max_sockets_per_pool(
12073 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12074
12075 // Set up SSL request.
12076
12077 HttpRequestInfo ssl_request;
12078 ssl_request.method = "GET";
12079 ssl_request.url = GURL("https://www.google.com/");
12080
12081 MockWrite ssl_writes[] = {
12082 MockWrite("GET / HTTP/1.1\r\n"
12083 "Host: www.google.com\r\n"
12084 "Connection: keep-alive\r\n\r\n"),
12085 };
12086 MockRead ssl_reads[] = {
12087 MockRead("HTTP/1.1 200 OK\r\n"),
12088 MockRead("Content-Length: 11\r\n\r\n"),
12089 MockRead("hello world"),
12090 MockRead(SYNCHRONOUS, OK),
12091 };
12092 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12093 ssl_writes, arraysize(ssl_writes));
12094 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12095
12096 SSLSocketDataProvider ssl(ASYNC, OK);
12097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12098
12099 // Set up HTTP request.
12100
12101 HttpRequestInfo http_request;
12102 http_request.method = "GET";
12103 http_request.url = GURL("http://www.google.com/");
12104
12105 MockWrite http_writes[] = {
12106 MockWrite("GET / HTTP/1.1\r\n"
12107 "Host: www.google.com\r\n"
12108 "Connection: keep-alive\r\n\r\n"),
12109 };
12110 MockRead http_reads[] = {
12111 MockRead("HTTP/1.1 200 OK\r\n"),
12112 MockRead("Content-Length: 7\r\n\r\n"),
12113 MockRead("falafel"),
12114 MockRead(SYNCHRONOUS, OK),
12115 };
12116 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12117 http_writes, arraysize(http_writes));
12118 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12119
12120 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12121
12122 // Start the SSL request.
12123 TestCompletionCallback ssl_callback;
12124 scoped_ptr<HttpTransaction> ssl_trans(
12125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12126 ASSERT_EQ(ERR_IO_PENDING,
12127 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12128 BoundNetLog()));
12129
12130 // Start the HTTP request. Pool should stall.
12131 TestCompletionCallback http_callback;
12132 scoped_ptr<HttpTransaction> http_trans(
12133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12134 ASSERT_EQ(ERR_IO_PENDING,
12135 http_trans->Start(&http_request, http_callback.callback(),
12136 BoundNetLog()));
12137 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12138
12139 // Wait for response from SSL request.
12140 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12141 std::string response_data;
12142 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12143 EXPECT_EQ("hello world", response_data);
12144
12145 // The SSL socket should automatically be closed, so the HTTP request can
12146 // start.
12147 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12148 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12149
12150 // The HTTP request can now complete.
12151 ASSERT_EQ(OK, http_callback.WaitForResult());
12152 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12153 EXPECT_EQ("falafel", response_data);
12154
12155 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12156}
12157
12158// Tests that when a SSL connection is established but there's no corresponding
12159// request that needs it, the new socket is closed if the transport socket pool
12160// is stalled on the global socket limit.
12161TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12162 ClientSocketPoolManager::set_max_sockets_per_group(
12163 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12164 ClientSocketPoolManager::set_max_sockets_per_pool(
12165 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12166
12167 // Set up an ssl request.
12168
12169 HttpRequestInfo ssl_request;
12170 ssl_request.method = "GET";
12171 ssl_request.url = GURL("https://www.foopy.com/");
12172
12173 // No data will be sent on the SSL socket.
12174 StaticSocketDataProvider ssl_data;
12175 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12176
12177 SSLSocketDataProvider ssl(ASYNC, OK);
12178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12179
12180 // Set up HTTP request.
12181
12182 HttpRequestInfo http_request;
12183 http_request.method = "GET";
12184 http_request.url = GURL("http://www.google.com/");
12185
12186 MockWrite http_writes[] = {
12187 MockWrite("GET / HTTP/1.1\r\n"
12188 "Host: www.google.com\r\n"
12189 "Connection: keep-alive\r\n\r\n"),
12190 };
12191 MockRead http_reads[] = {
12192 MockRead("HTTP/1.1 200 OK\r\n"),
12193 MockRead("Content-Length: 7\r\n\r\n"),
12194 MockRead("falafel"),
12195 MockRead(SYNCHRONOUS, OK),
12196 };
12197 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12198 http_writes, arraysize(http_writes));
12199 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12200
12201 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12202
12203 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12204 // cancelled when a normal transaction is cancelled.
12205 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12206 net::SSLConfig ssl_config;
12207 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12208 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12209 ssl_config, ssl_config);
12210 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12211
12212 // Start the HTTP request. Pool should stall.
12213 TestCompletionCallback http_callback;
12214 scoped_ptr<HttpTransaction> http_trans(
12215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12216 ASSERT_EQ(ERR_IO_PENDING,
12217 http_trans->Start(&http_request, http_callback.callback(),
12218 BoundNetLog()));
12219 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12220
12221 // The SSL connection will automatically be closed once the connection is
12222 // established, to let the HTTP request start.
12223 ASSERT_EQ(OK, http_callback.WaitForResult());
12224 std::string response_data;
12225 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12226 EXPECT_EQ("falafel", response_data);
12227
12228 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12229}
12230
[email protected]89ceba9a2009-03-21 03:46:0612231} // namespace net