blob: 661218087d8cffc4f656bb0e8029b93f0a89b6cb [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]b05bcaa32013-10-06 05:26:02389 testing::Values(kProtoDeprecatedSPDY2,
390 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
[email protected]88a332622013-07-30 07:13:32391 kProtoHTTP2Draft04));
[email protected]23e482282013-06-14 16:08:02392
[email protected]448d4ca52012-03-04 04:12:23393namespace {
394
[email protected]15a5ccf82008-10-23 19:57:43395// Fill |str| with a long header list that consumes >= |size| bytes.
396void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19397 const char* row =
398 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
399 const int sizeof_row = strlen(row);
400 const int num_rows = static_cast<int>(
401 ceil(static_cast<float>(size) / sizeof_row));
402 const int sizeof_data = num_rows * sizeof_row;
403 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43404 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51405
[email protected]4ddaf2502008-10-23 18:26:19406 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43407 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19408}
409
[email protected]385a4672009-03-11 22:21:29410// Alternative functions that eliminate randomness and dependency on the local
411// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20412void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29413 static const uint8 bytes[] = {
414 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
415 };
416 static size_t current_byte = 0;
417 for (size_t i = 0; i < n; ++i) {
418 output[i] = bytes[current_byte++];
419 current_byte %= arraysize(bytes);
420 }
421}
422
[email protected]fe2bc6a2009-03-23 16:52:20423void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29424 static const uint8 bytes[] = {
425 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
426 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
427 };
428 static size_t current_byte = 0;
429 for (size_t i = 0; i < n; ++i) {
430 output[i] = bytes[current_byte++];
431 current_byte %= arraysize(bytes);
432 }
433}
434
[email protected]fe2bc6a2009-03-23 16:52:20435std::string MockGetHostName() {
436 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29437}
438
[email protected]e60e47a2010-07-14 03:37:18439template<typename ParentPool>
440class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31441 public:
[email protected]9e1bdd32011-02-03 21:48:34442 CaptureGroupNameSocketPool(HostResolver* host_resolver,
443 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18444
[email protected]d80a4322009-08-14 07:07:49445 const std::string last_group_name_received() const {
446 return last_group_name_;
447 }
448
[email protected]684970b2009-08-14 04:54:46449 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49450 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31451 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31452 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41453 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53454 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31455 last_group_name_ = group_name;
456 return ERR_IO_PENDING;
457 }
[email protected]04e5be32009-06-26 20:00:31458 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21459 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31460 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44461 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19462 int id) {}
[email protected]04e5be32009-06-26 20:00:31463 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31464 virtual int IdleSocketCount() const {
465 return 0;
466 }
467 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
468 return 0;
469 }
470 virtual LoadState GetLoadState(const std::string& group_name,
471 const ClientSocketHandle* handle) const {
472 return LOAD_STATE_IDLE;
473 }
[email protected]a796bcec2010-03-22 17:17:26474 virtual base::TimeDelta ConnectionTimeout() const {
475 return base::TimeDelta();
476 }
[email protected]d80a4322009-08-14 07:07:49477
478 private:
[email protected]04e5be32009-06-26 20:00:31479 std::string last_group_name_;
480};
481
[email protected]ab739042011-04-07 15:22:28482typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
483CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13484typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
485CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06486typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11487CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18488typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
489CaptureGroupNameSSLSocketPool;
490
491template<typename ParentPool>
492CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34493 HostResolver* host_resolver,
494 CertVerifier* /* cert_verifier */)
495 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18496
497template<>
[email protected]2df19bb2010-08-25 20:13:46498CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34499 HostResolver* host_resolver,
500 CertVerifier* /* cert_verifier */)
501 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46502
[email protected]007b3f82013-04-09 08:46:45503template <>
[email protected]e60e47a2010-07-14 03:37:18504CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34505 HostResolver* host_resolver,
506 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45507 : SSLClientSocketPool(0,
508 0,
509 NULL,
510 host_resolver,
511 cert_verifier,
512 NULL,
513 NULL,
514 std::string(),
515 NULL,
516 NULL,
517 NULL,
518 NULL,
519 NULL,
520 NULL) {}
[email protected]2227c692010-05-04 15:36:11521
[email protected]231d5a32008-09-13 00:45:27522//-----------------------------------------------------------------------------
523
[email protected]79cb5c12011-09-12 13:12:04524// Helper functions for validating that AuthChallengeInfo's are correctly
525// configured for common cases.
526bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
527 if (!auth_challenge)
528 return false;
529 EXPECT_FALSE(auth_challenge->is_proxy);
530 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
531 EXPECT_EQ("MyRealm1", auth_challenge->realm);
532 EXPECT_EQ("basic", auth_challenge->scheme);
533 return true;
534}
535
536bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
537 if (!auth_challenge)
538 return false;
539 EXPECT_TRUE(auth_challenge->is_proxy);
540 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
541 EXPECT_EQ("MyRealm1", auth_challenge->realm);
542 EXPECT_EQ("basic", auth_challenge->scheme);
543 return true;
544}
545
546bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
547 if (!auth_challenge)
548 return false;
549 EXPECT_FALSE(auth_challenge->is_proxy);
550 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
551 EXPECT_EQ("digestive", auth_challenge->realm);
552 EXPECT_EQ("digest", auth_challenge->scheme);
553 return true;
554}
555
556bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
557 if (!auth_challenge)
558 return false;
559 EXPECT_FALSE(auth_challenge->is_proxy);
560 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
561 EXPECT_EQ(std::string(), auth_challenge->realm);
562 EXPECT_EQ("ntlm", auth_challenge->scheme);
563 return true;
564}
565
[email protected]448d4ca52012-03-04 04:12:23566} // namespace
567
[email protected]23e482282013-06-14 16:08:02568TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]d207a5f2009-06-04 05:28:40569 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36570 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07571 CreateSession(&session_deps_)));
[email protected]231d5a32008-09-13 00:45:27572}
573
[email protected]23e482282013-06-14 16:08:02574TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27575 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35576 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
577 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06578 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27579 };
[email protected]31a2bfe2010-02-09 08:03:39580 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
581 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42582 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27583 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
584 EXPECT_EQ("hello world", out.response_data);
585}
586
587// Response with no status line.
[email protected]23e482282013-06-14 16:08:02588TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27589 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35590 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06591 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27592 };
[email protected]31a2bfe2010-02-09 08:03:39593 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
594 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42595 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27596 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
597 EXPECT_EQ("hello world", out.response_data);
598}
599
600// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02601TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27602 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35603 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06604 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27605 };
[email protected]31a2bfe2010-02-09 08:03:39606 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
607 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42608 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27609 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
610 EXPECT_EQ("DATA", out.response_data);
611}
612
613// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02614TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27615 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35616 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06617 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27618 };
[email protected]31a2bfe2010-02-09 08:03:39619 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
620 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42621 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27622 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
623 EXPECT_EQ("DATA", out.response_data);
624}
625
626// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02627TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27628 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35629 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06630 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27631 };
[email protected]31a2bfe2010-02-09 08:03:39632 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
633 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42634 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25635 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
636 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27637}
638
639// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02640TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27641 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35642 MockRead("\n"),
643 MockRead("\n"),
644 MockRead("Q"),
645 MockRead("J"),
646 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06647 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27648 };
[email protected]31a2bfe2010-02-09 08:03:39649 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
650 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42651 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27652 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
653 EXPECT_EQ("DATA", out.response_data);
654}
655
656// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02657TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27658 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35659 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06660 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27661 };
[email protected]31a2bfe2010-02-09 08:03:39662 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
663 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42664 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27665 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
666 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52667}
668
[email protected]f9d44aa2008-09-23 23:57:17669// Simulate a 204 response, lacking a Content-Length header, sent over a
670// persistent connection. The response should still terminate since a 204
671// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02672TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]f9d44aa2008-09-23 23:57:17673 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35674 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
675 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06676 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17677 };
[email protected]31a2bfe2010-02-09 08:03:39678 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
679 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42680 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17681 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
682 EXPECT_EQ("", out.response_data);
683}
684
[email protected]0877e3d2009-10-17 22:29:57685// A simple request using chunked encoding with some extra data after.
686// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02687TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]0877e3d2009-10-17 22:29:57688 MockRead data_reads[] = {
689 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
690 MockRead("5\r\nHello\r\n"),
691 MockRead("1\r\n"),
692 MockRead(" \r\n"),
693 MockRead("5\r\nworld\r\n"),
694 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06695 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57696 };
[email protected]31a2bfe2010-02-09 08:03:39697 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
698 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57699 EXPECT_EQ(OK, out.rv);
700 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
701 EXPECT_EQ("Hello world", out.response_data);
702}
703
[email protected]9fe44f52010-09-23 18:36:00704// Next tests deal with http://crbug.com/56344.
705
[email protected]23e482282013-06-14 16:08:02706TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00707 MultipleContentLengthHeadersNoTransferEncoding) {
708 MockRead data_reads[] = {
709 MockRead("HTTP/1.1 200 OK\r\n"),
710 MockRead("Content-Length: 10\r\n"),
711 MockRead("Content-Length: 5\r\n\r\n"),
712 };
713 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
714 arraysize(data_reads));
715 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
716}
717
[email protected]23e482282013-06-14 16:08:02718TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04719 DuplicateContentLengthHeadersNoTransferEncoding) {
720 MockRead data_reads[] = {
721 MockRead("HTTP/1.1 200 OK\r\n"),
722 MockRead("Content-Length: 5\r\n"),
723 MockRead("Content-Length: 5\r\n\r\n"),
724 MockRead("Hello"),
725 };
726 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
727 arraysize(data_reads));
728 EXPECT_EQ(OK, out.rv);
729 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
730 EXPECT_EQ("Hello", out.response_data);
731}
732
[email protected]23e482282013-06-14 16:08:02733TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04734 ComplexContentLengthHeadersNoTransferEncoding) {
735 // More than 2 dupes.
736 {
737 MockRead data_reads[] = {
738 MockRead("HTTP/1.1 200 OK\r\n"),
739 MockRead("Content-Length: 5\r\n"),
740 MockRead("Content-Length: 5\r\n"),
741 MockRead("Content-Length: 5\r\n\r\n"),
742 MockRead("Hello"),
743 };
744 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
745 arraysize(data_reads));
746 EXPECT_EQ(OK, out.rv);
747 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
748 EXPECT_EQ("Hello", out.response_data);
749 }
750 // HTTP/1.0
751 {
752 MockRead data_reads[] = {
753 MockRead("HTTP/1.0 200 OK\r\n"),
754 MockRead("Content-Length: 5\r\n"),
755 MockRead("Content-Length: 5\r\n"),
756 MockRead("Content-Length: 5\r\n\r\n"),
757 MockRead("Hello"),
758 };
759 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
760 arraysize(data_reads));
761 EXPECT_EQ(OK, out.rv);
762 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
763 EXPECT_EQ("Hello", out.response_data);
764 }
765 // 2 dupes and one mismatched.
766 {
767 MockRead data_reads[] = {
768 MockRead("HTTP/1.1 200 OK\r\n"),
769 MockRead("Content-Length: 10\r\n"),
770 MockRead("Content-Length: 10\r\n"),
771 MockRead("Content-Length: 5\r\n\r\n"),
772 };
773 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
774 arraysize(data_reads));
775 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
776 }
777}
778
[email protected]23e482282013-06-14 16:08:02779TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00780 MultipleContentLengthHeadersTransferEncoding) {
781 MockRead data_reads[] = {
782 MockRead("HTTP/1.1 200 OK\r\n"),
783 MockRead("Content-Length: 666\r\n"),
784 MockRead("Content-Length: 1337\r\n"),
785 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
786 MockRead("5\r\nHello\r\n"),
787 MockRead("1\r\n"),
788 MockRead(" \r\n"),
789 MockRead("5\r\nworld\r\n"),
790 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06791 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00792 };
793 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
794 arraysize(data_reads));
795 EXPECT_EQ(OK, out.rv);
796 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
797 EXPECT_EQ("Hello world", out.response_data);
798}
799
[email protected]1628fe92011-10-04 23:04:55800// Next tests deal with http://crbug.com/98895.
801
802// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02803TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55804 MockRead data_reads[] = {
805 MockRead("HTTP/1.1 200 OK\r\n"),
806 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
807 MockRead("Content-Length: 5\r\n\r\n"),
808 MockRead("Hello"),
809 };
810 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
811 arraysize(data_reads));
812 EXPECT_EQ(OK, out.rv);
813 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
814 EXPECT_EQ("Hello", out.response_data);
815}
816
[email protected]54a9c6e52012-03-21 20:10:59817// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02818TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59819 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55820 MockRead data_reads[] = {
821 MockRead("HTTP/1.1 200 OK\r\n"),
822 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
823 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
824 MockRead("Content-Length: 5\r\n\r\n"),
825 MockRead("Hello"),
826 };
827 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
828 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59829 EXPECT_EQ(OK, out.rv);
830 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
831 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55832}
833
834// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02835TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55836 MockRead data_reads[] = {
837 MockRead("HTTP/1.1 200 OK\r\n"),
838 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
839 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
840 MockRead("Content-Length: 5\r\n\r\n"),
841 MockRead("Hello"),
842 };
843 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
844 arraysize(data_reads));
845 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
846}
847
[email protected]54a9c6e52012-03-21 20:10:59848// Checks that two identical Location headers result in no error.
849// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02850TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55851 MockRead data_reads[] = {
852 MockRead("HTTP/1.1 302 Redirect\r\n"),
853 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59854 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55855 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06856 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55857 };
858
859 HttpRequestInfo request;
860 request.method = "GET";
861 request.url = GURL("http://redirect.com/");
862 request.load_flags = 0;
863
[email protected]1628fe92011-10-04 23:04:55864 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36865 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07866 CreateSession(&session_deps_)));
[email protected]1628fe92011-10-04 23:04:55867
868 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07869 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55870
[email protected]49639fa2011-12-20 23:22:41871 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55872
[email protected]49639fa2011-12-20 23:22:41873 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55874 EXPECT_EQ(ERR_IO_PENDING, rv);
875
876 EXPECT_EQ(OK, callback.WaitForResult());
877
878 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50879 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55880 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
881 std::string url;
882 EXPECT_TRUE(response->headers->IsRedirect(&url));
883 EXPECT_EQ("http://good.com/", url);
884}
885
[email protected]1628fe92011-10-04 23:04:55886// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02887TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55888 MockRead data_reads[] = {
889 MockRead("HTTP/1.1 302 Redirect\r\n"),
890 MockRead("Location: http://good.com/\r\n"),
891 MockRead("Location: http://evil.com/\r\n"),
892 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06893 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55894 };
895 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
896 arraysize(data_reads));
897 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
898}
899
[email protected]ef0faf2e72009-03-05 23:27:23900// Do a request using the HEAD method. Verify that we don't try to read the
901// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02902TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42903 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23904 request.method = "HEAD";
905 request.url = GURL("http://www.google.com/");
906 request.load_flags = 0;
907
[email protected]cb9bf6ca2011-01-28 13:15:27908 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36909 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07910 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:27911
[email protected]ef0faf2e72009-03-05 23:27:23912 MockWrite data_writes1[] = {
913 MockWrite("HEAD / HTTP/1.1\r\n"
914 "Host: www.google.com\r\n"
915 "Connection: keep-alive\r\n"
916 "Content-Length: 0\r\n\r\n"),
917 };
918 MockRead data_reads1[] = {
919 MockRead("HTTP/1.1 404 Not Found\r\n"),
920 MockRead("Server: Blah\r\n"),
921 MockRead("Content-Length: 1234\r\n\r\n"),
922
923 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06924 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23925 };
926
[email protected]31a2bfe2010-02-09 08:03:39927 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
928 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07929 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23930
[email protected]49639fa2011-12-20 23:22:41931 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23932
[email protected]49639fa2011-12-20 23:22:41933 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42934 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23935
936 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42937 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23938
[email protected]1c773ea12009-04-28 19:58:42939 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50940 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23941
942 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:50943 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23944 EXPECT_EQ(1234, response->headers->GetContentLength());
945 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
946
947 std::string server_header;
948 void* iter = NULL;
949 bool has_server_header = response->headers->EnumerateHeader(
950 &iter, "Server", &server_header);
951 EXPECT_TRUE(has_server_header);
952 EXPECT_EQ("Blah", server_header);
953
954 // Reading should give EOF right away, since there is no message body
955 // (despite non-zero content-length).
956 std::string response_data;
957 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42958 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23959 EXPECT_EQ("", response_data);
960}
961
[email protected]23e482282013-06-14 16:08:02962TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:07963 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:52964
965 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35966 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
967 MockRead("hello"),
968 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
969 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:06970 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:52971 };
[email protected]31a2bfe2010-02-09 08:03:39972 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07973 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52974
[email protected]0b0bf032010-09-21 18:08:50975 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:52976 "hello", "world"
977 };
978
979 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42980 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52981 request.method = "GET";
982 request.url = GURL("http://www.google.com/");
983 request.load_flags = 0;
984
[email protected]262eec82013-03-19 21:01:36985 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:50986 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27987
[email protected]49639fa2011-12-20 23:22:41988 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52989
[email protected]49639fa2011-12-20 23:22:41990 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42991 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52992
993 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42994 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52995
[email protected]1c773ea12009-04-28 19:58:42996 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50997 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:52998
[email protected]90499482013-06-01 00:39:50999 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251000 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521001
1002 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571003 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421004 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251005 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521006 }
1007}
1008
[email protected]23e482282013-06-14 16:08:021009TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061010 ScopedVector<UploadElementReader> element_readers;
1011 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201012 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271013
[email protected]1c773ea12009-04-28 19:58:421014 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521015 request.method = "POST";
1016 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271017 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521018 request.load_flags = 0;
1019
[email protected]cb9bf6ca2011-01-28 13:15:271020 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361021 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071022 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271023
initial.commit586acc5fe2008-07-26 22:42:521024 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351025 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1026 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1027 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061028 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521029 };
[email protected]31a2bfe2010-02-09 08:03:391030 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071031 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521032
[email protected]49639fa2011-12-20 23:22:411033 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521034
[email protected]49639fa2011-12-20 23:22:411035 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421036 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521037
1038 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421039 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521040
[email protected]1c773ea12009-04-28 19:58:421041 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501042 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521043
[email protected]90499482013-06-01 00:39:501044 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251045 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521046
1047 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571048 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421049 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251050 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521051}
1052
[email protected]3a2d3662009-03-27 03:49:141053// This test is almost the same as Ignores100 above, but the response contains
1054// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571055// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021056TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421057 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141058 request.method = "GET";
1059 request.url = GURL("http://www.foo.com/");
1060 request.load_flags = 0;
1061
[email protected]cb9bf6ca2011-01-28 13:15:271062 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361063 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071064 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271065
[email protected]3a2d3662009-03-27 03:49:141066 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571067 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1068 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141069 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061070 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141071 };
[email protected]31a2bfe2010-02-09 08:03:391072 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071073 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141074
[email protected]49639fa2011-12-20 23:22:411075 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141076
[email protected]49639fa2011-12-20 23:22:411077 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421078 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141079
1080 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421081 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141082
[email protected]1c773ea12009-04-28 19:58:421083 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501084 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141085
[email protected]90499482013-06-01 00:39:501086 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141087 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1088
1089 std::string response_data;
1090 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421091 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141092 EXPECT_EQ("hello world", response_data);
1093}
1094
[email protected]23e482282013-06-14 16:08:021095TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381096 HttpRequestInfo request;
1097 request.method = "POST";
1098 request.url = GURL("http://www.foo.com/");
1099 request.load_flags = 0;
1100
[email protected]cb9bf6ca2011-01-28 13:15:271101 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361102 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071103 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271104
[email protected]ee9410e72010-01-07 01:42:381105 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061106 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1107 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381108 };
[email protected]31a2bfe2010-02-09 08:03:391109 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071110 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381111
[email protected]49639fa2011-12-20 23:22:411112 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381113
[email protected]49639fa2011-12-20 23:22:411114 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381115 EXPECT_EQ(ERR_IO_PENDING, rv);
1116
1117 rv = callback.WaitForResult();
1118 EXPECT_EQ(OK, rv);
1119
1120 std::string response_data;
1121 rv = ReadTransaction(trans.get(), &response_data);
1122 EXPECT_EQ(OK, rv);
1123 EXPECT_EQ("", response_data);
1124}
1125
[email protected]23e482282013-06-14 16:08:021126TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381127 HttpRequestInfo request;
1128 request.method = "POST";
1129 request.url = GURL("http://www.foo.com/");
1130 request.load_flags = 0;
1131
[email protected]cb9bf6ca2011-01-28 13:15:271132 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361133 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071134 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271135
[email protected]ee9410e72010-01-07 01:42:381136 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061137 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381138 };
[email protected]31a2bfe2010-02-09 08:03:391139 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071140 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381141
[email protected]49639fa2011-12-20 23:22:411142 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381143
[email protected]49639fa2011-12-20 23:22:411144 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381145 EXPECT_EQ(ERR_IO_PENDING, rv);
1146
1147 rv = callback.WaitForResult();
1148 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1149}
1150
[email protected]23e482282013-06-14 16:08:021151void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511152 const MockWrite* write_failure,
1153 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421154 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521155 request.method = "GET";
1156 request.url = GURL("http://www.foo.com/");
1157 request.load_flags = 0;
1158
[email protected]58e32bb2013-01-21 18:23:251159 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071160 session_deps_.net_log = &net_log;
1161 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271162
[email protected]202965992011-12-07 23:04:511163 // Written data for successfully sending both requests.
1164 MockWrite data1_writes[] = {
1165 MockWrite("GET / HTTP/1.1\r\n"
1166 "Host: www.foo.com\r\n"
1167 "Connection: keep-alive\r\n\r\n"),
1168 MockWrite("GET / HTTP/1.1\r\n"
1169 "Host: www.foo.com\r\n"
1170 "Connection: keep-alive\r\n\r\n")
1171 };
1172
1173 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521174 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351175 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1176 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061177 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521178 };
[email protected]202965992011-12-07 23:04:511179
1180 if (write_failure) {
1181 ASSERT_TRUE(!read_failure);
1182 data1_writes[1] = *write_failure;
1183 } else {
1184 ASSERT_TRUE(read_failure);
1185 data1_reads[2] = *read_failure;
1186 }
1187
1188 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1189 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521191
1192 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351193 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1194 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061195 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521196 };
[email protected]31a2bfe2010-02-09 08:03:391197 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071198 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521199
1200 const char* kExpectedResponseData[] = {
1201 "hello", "world"
1202 };
1203
[email protected]58e32bb2013-01-21 18:23:251204 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521205 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411206 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521207
[email protected]262eec82013-03-19 21:01:361208 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521210
[email protected]49639fa2011-12-20 23:22:411211 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421212 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521213
1214 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421215 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521216
[email protected]58e32bb2013-01-21 18:23:251217 LoadTimingInfo load_timing_info;
1218 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1219 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1220 if (i == 0) {
1221 first_socket_log_id = load_timing_info.socket_log_id;
1222 } else {
1223 // The second request should be using a new socket.
1224 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1225 }
1226
[email protected]1c773ea12009-04-28 19:58:421227 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501228 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521229
[email protected]90499482013-06-01 00:39:501230 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251231 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521232
1233 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571234 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421235 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251236 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521237 }
1238}
[email protected]3d2a59b2008-09-26 19:44:251239
[email protected]23e482282013-06-14 16:08:021240TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231241 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061242 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511243 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1244}
1245
[email protected]23e482282013-06-14 16:08:021246TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061247 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511248 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251249}
1250
[email protected]23e482282013-06-14 16:08:021251TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061252 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511253 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251254}
1255
[email protected]23e482282013-06-14 16:08:021256TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421257 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251258 request.method = "GET";
1259 request.url = GURL("http://www.google.com/");
1260 request.load_flags = 0;
1261
[email protected]cb9bf6ca2011-01-28 13:15:271262 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361263 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071264 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271265
[email protected]3d2a59b2008-09-26 19:44:251266 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061267 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351268 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1269 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061270 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251271 };
[email protected]31a2bfe2010-02-09 08:03:391272 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071273 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251274
[email protected]49639fa2011-12-20 23:22:411275 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251276
[email protected]49639fa2011-12-20 23:22:411277 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421278 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251279
1280 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421281 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251282
[email protected]1c773ea12009-04-28 19:58:421283 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251284 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251285}
1286
1287// What do various browsers do when the server closes a non-keepalive
1288// connection without sending any response header or body?
1289//
1290// IE7: error page
1291// Safari 3.1.2 (Windows): error page
1292// Firefox 3.0.1: blank page
1293// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421294// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1295// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021296TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251297 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061298 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351299 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1300 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061301 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251302 };
[email protected]31a2bfe2010-02-09 08:03:391303 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1304 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421305 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251306}
[email protected]038e9a32008-10-08 22:40:161307
[email protected]7a5378b2012-11-04 03:25:171308// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1309// tests. There was a bug causing HttpNetworkTransaction to hang in the
1310// destructor in such situations.
1311// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021312TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171313 HttpRequestInfo request;
1314 request.method = "GET";
1315 request.url = GURL("http://www.google.com/");
1316 request.load_flags = 0;
1317
[email protected]bb88e1d32013-05-03 23:11:071318 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361319 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501320 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171321
1322 MockRead data_reads[] = {
1323 MockRead("HTTP/1.0 200 OK\r\n"),
1324 MockRead("Connection: keep-alive\r\n"),
1325 MockRead("Content-Length: 100\r\n\r\n"),
1326 MockRead("hello"),
1327 MockRead(SYNCHRONOUS, 0),
1328 };
1329 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071330 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171331
1332 TestCompletionCallback callback;
1333
1334 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1335 EXPECT_EQ(ERR_IO_PENDING, rv);
1336
1337 rv = callback.WaitForResult();
1338 EXPECT_EQ(OK, rv);
1339
1340 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501341 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171342 if (rv == ERR_IO_PENDING)
1343 rv = callback.WaitForResult();
1344 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501345 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171346 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1347
1348 trans.reset();
[email protected]2da659e2013-05-23 20:51:341349 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171350 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1351}
1352
[email protected]23e482282013-06-14 16:08:021353TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171354 HttpRequestInfo request;
1355 request.method = "GET";
1356 request.url = GURL("http://www.google.com/");
1357 request.load_flags = 0;
1358
[email protected]bb88e1d32013-05-03 23:11:071359 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361360 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171362
1363 MockRead data_reads[] = {
1364 MockRead("HTTP/1.0 200 OK\r\n"),
1365 MockRead("Connection: keep-alive\r\n"),
1366 MockRead("Content-Length: 100\r\n\r\n"),
1367 MockRead(SYNCHRONOUS, 0),
1368 };
1369 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071370 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171371
1372 TestCompletionCallback callback;
1373
1374 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1375 EXPECT_EQ(ERR_IO_PENDING, rv);
1376
1377 rv = callback.WaitForResult();
1378 EXPECT_EQ(OK, rv);
1379
1380 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501381 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171382 if (rv == ERR_IO_PENDING)
1383 rv = callback.WaitForResult();
1384 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1385
1386 trans.reset();
[email protected]2da659e2013-05-23 20:51:341387 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171388 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1389}
1390
[email protected]0b0bf032010-09-21 18:08:501391// Test that we correctly reuse a keep-alive connection after not explicitly
1392// reading the body.
[email protected]23e482282013-06-14 16:08:021393TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131394 HttpRequestInfo request;
1395 request.method = "GET";
1396 request.url = GURL("http://www.foo.com/");
1397 request.load_flags = 0;
1398
[email protected]58e32bb2013-01-21 18:23:251399 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071400 session_deps_.net_log = &net_log;
1401 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271402
[email protected]0b0bf032010-09-21 18:08:501403 // Note that because all these reads happen in the same
1404 // StaticSocketDataProvider, it shows that the same socket is being reused for
1405 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131406 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501407 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1408 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131409 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501410 MockRead("HTTP/1.1 302 Found\r\n"
1411 "Content-Length: 0\r\n\r\n"),
1412 MockRead("HTTP/1.1 302 Found\r\n"
1413 "Content-Length: 5\r\n\r\n"
1414 "hello"),
1415 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1416 "Content-Length: 0\r\n\r\n"),
1417 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1418 "Content-Length: 5\r\n\r\n"
1419 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131420 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1421 MockRead("hello"),
1422 };
1423 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131425
1426 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061427 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131428 };
1429 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071430 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131431
[email protected]0b0bf032010-09-21 18:08:501432 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1433 std::string response_lines[kNumUnreadBodies];
1434
[email protected]58e32bb2013-01-21 18:23:251435 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501436 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411437 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131438
[email protected]262eec82013-03-19 21:01:361439 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501440 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131441
[email protected]49639fa2011-12-20 23:22:411442 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131443 EXPECT_EQ(ERR_IO_PENDING, rv);
1444
1445 rv = callback.WaitForResult();
1446 EXPECT_EQ(OK, rv);
1447
[email protected]58e32bb2013-01-21 18:23:251448 LoadTimingInfo load_timing_info;
1449 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1450 if (i == 0) {
1451 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1452 first_socket_log_id = load_timing_info.socket_log_id;
1453 } else {
1454 TestLoadTimingReused(load_timing_info);
1455 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1456 }
1457
[email protected]fc31d6a42010-06-24 18:05:131458 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501459 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131460
[email protected]90499482013-06-01 00:39:501461 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501462 response_lines[i] = response->headers->GetStatusLine();
1463
1464 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131465 }
[email protected]0b0bf032010-09-21 18:08:501466
1467 const char* const kStatusLines[] = {
1468 "HTTP/1.1 204 No Content",
1469 "HTTP/1.1 205 Reset Content",
1470 "HTTP/1.1 304 Not Modified",
1471 "HTTP/1.1 302 Found",
1472 "HTTP/1.1 302 Found",
1473 "HTTP/1.1 301 Moved Permanently",
1474 "HTTP/1.1 301 Moved Permanently",
1475 };
1476
1477 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1478 forgot_to_update_kStatusLines);
1479
1480 for (int i = 0; i < kNumUnreadBodies; ++i)
1481 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1482
[email protected]49639fa2011-12-20 23:22:411483 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361484 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411486 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501487 EXPECT_EQ(ERR_IO_PENDING, rv);
1488 rv = callback.WaitForResult();
1489 EXPECT_EQ(OK, rv);
1490 const HttpResponseInfo* response = trans->GetResponseInfo();
1491 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501492 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501493 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1494 std::string response_data;
1495 rv = ReadTransaction(trans.get(), &response_data);
1496 EXPECT_EQ(OK, rv);
1497 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131498}
1499
[email protected]038e9a32008-10-08 22:40:161500// Test the request-challenge-retry sequence for basic auth.
1501// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021502TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421503 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161504 request.method = "GET";
1505 request.url = GURL("http://www.google.com/");
1506 request.load_flags = 0;
1507
[email protected]58e32bb2013-01-21 18:23:251508 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071509 session_deps_.net_log = &log;
[email protected]cb9bf6ca2011-01-28 13:15:271510 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361511 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071512 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271513
[email protected]f9ee6b52008-11-08 06:46:231514 MockWrite data_writes1[] = {
1515 MockWrite("GET / HTTP/1.1\r\n"
1516 "Host: www.google.com\r\n"
1517 "Connection: keep-alive\r\n\r\n"),
1518 };
1519
[email protected]038e9a32008-10-08 22:40:161520 MockRead data_reads1[] = {
1521 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1522 // Give a couple authenticate options (only the middle one is actually
1523 // supported).
[email protected]22927ad2009-09-21 19:56:191524 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161525 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1526 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1527 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1528 // Large content-length -- won't matter, as connection will be reset.
1529 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061530 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161531 };
1532
1533 // After calling trans->RestartWithAuth(), this is the request we should
1534 // be issuing -- the final header line contains the credentials.
1535 MockWrite data_writes2[] = {
1536 MockWrite("GET / HTTP/1.1\r\n"
1537 "Host: www.google.com\r\n"
1538 "Connection: keep-alive\r\n"
1539 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1540 };
1541
1542 // Lastly, the server responds with the actual content.
1543 MockRead data_reads2[] = {
1544 MockRead("HTTP/1.0 200 OK\r\n"),
1545 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1546 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061547 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161548 };
1549
[email protected]31a2bfe2010-02-09 08:03:391550 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1551 data_writes1, arraysize(data_writes1));
1552 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1553 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071554 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1555 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161556
[email protected]49639fa2011-12-20 23:22:411557 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161558
[email protected]49639fa2011-12-20 23:22:411559 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421560 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161561
1562 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421563 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161564
[email protected]58e32bb2013-01-21 18:23:251565 LoadTimingInfo load_timing_info1;
1566 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1567 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1568
[email protected]1c773ea12009-04-28 19:58:421569 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501570 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041571 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161572
[email protected]49639fa2011-12-20 23:22:411573 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161574
[email protected]49639fa2011-12-20 23:22:411575 rv = trans->RestartWithAuth(
1576 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421577 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161578
1579 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421580 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161581
[email protected]58e32bb2013-01-21 18:23:251582 LoadTimingInfo load_timing_info2;
1583 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1584 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1585 // The load timing after restart should have a new socket ID, and times after
1586 // those of the first load timing.
1587 EXPECT_LE(load_timing_info1.receive_headers_end,
1588 load_timing_info2.connect_timing.connect_start);
1589 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1590
[email protected]038e9a32008-10-08 22:40:161591 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501592 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161593 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1594 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161595}
1596
[email protected]23e482282013-06-14 16:08:021597TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461598 HttpRequestInfo request;
1599 request.method = "GET";
1600 request.url = GURL("http://www.google.com/");
1601 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1602
[email protected]cb9bf6ca2011-01-28 13:15:271603 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361604 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071605 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271606
[email protected]861fcd52009-08-26 02:33:461607 MockWrite data_writes[] = {
1608 MockWrite("GET / HTTP/1.1\r\n"
1609 "Host: www.google.com\r\n"
1610 "Connection: keep-alive\r\n\r\n"),
1611 };
1612
1613 MockRead data_reads[] = {
1614 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1615 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1616 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1617 // Large content-length -- won't matter, as connection will be reset.
1618 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061619 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461620 };
1621
[email protected]31a2bfe2010-02-09 08:03:391622 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1623 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071624 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411625 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461626
[email protected]49639fa2011-12-20 23:22:411627 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461628 EXPECT_EQ(ERR_IO_PENDING, rv);
1629
1630 rv = callback.WaitForResult();
1631 EXPECT_EQ(0, rv);
1632
1633 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501634 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461635 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1636}
1637
[email protected]2d2697f92009-02-18 21:00:321638// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1639// connection.
[email protected]23e482282013-06-14 16:08:021640TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421641 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321642 request.method = "GET";
1643 request.url = GURL("http://www.google.com/");
1644 request.load_flags = 0;
1645
[email protected]58e32bb2013-01-21 18:23:251646 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071647 session_deps_.net_log = &log;
1648 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271649
[email protected]2d2697f92009-02-18 21:00:321650 MockWrite data_writes1[] = {
1651 MockWrite("GET / HTTP/1.1\r\n"
1652 "Host: www.google.com\r\n"
1653 "Connection: keep-alive\r\n\r\n"),
1654
1655 // After calling trans->RestartWithAuth(), this is the request we should
1656 // be issuing -- the final header line contains the credentials.
1657 MockWrite("GET / HTTP/1.1\r\n"
1658 "Host: www.google.com\r\n"
1659 "Connection: keep-alive\r\n"
1660 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1661 };
1662
1663 MockRead data_reads1[] = {
1664 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1665 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1666 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1667 MockRead("Content-Length: 14\r\n\r\n"),
1668 MockRead("Unauthorized\r\n"),
1669
1670 // Lastly, the server responds with the actual content.
1671 MockRead("HTTP/1.1 200 OK\r\n"),
1672 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501673 MockRead("Content-Length: 5\r\n\r\n"),
1674 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321675 };
1676
[email protected]2d0a4f92011-05-05 16:38:461677 // If there is a regression where we disconnect a Keep-Alive
1678 // connection during an auth roundtrip, we'll end up reading this.
1679 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061680 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461681 };
1682
[email protected]31a2bfe2010-02-09 08:03:391683 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1684 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461685 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1686 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071687 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1688 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321689
[email protected]49639fa2011-12-20 23:22:411690 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321691
[email protected]262eec82013-03-19 21:01:361692 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501693 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411694 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421695 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321696
1697 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421698 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321699
[email protected]58e32bb2013-01-21 18:23:251700 LoadTimingInfo load_timing_info1;
1701 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1702 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1703
[email protected]1c773ea12009-04-28 19:58:421704 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501705 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041706 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321707
[email protected]49639fa2011-12-20 23:22:411708 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321709
[email protected]49639fa2011-12-20 23:22:411710 rv = trans->RestartWithAuth(
1711 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421712 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321713
1714 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421715 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321716
[email protected]58e32bb2013-01-21 18:23:251717 LoadTimingInfo load_timing_info2;
1718 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1719 TestLoadTimingReused(load_timing_info2);
1720 // The load timing after restart should have the same socket ID, and times
1721 // those of the first load timing.
1722 EXPECT_LE(load_timing_info1.receive_headers_end,
1723 load_timing_info2.send_start);
1724 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1725
[email protected]2d2697f92009-02-18 21:00:321726 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501727 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321728 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501729 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321730}
1731
1732// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1733// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021734TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421735 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321736 request.method = "GET";
1737 request.url = GURL("http://www.google.com/");
1738 request.load_flags = 0;
1739
[email protected]bb88e1d32013-05-03 23:11:071740 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271741
[email protected]2d2697f92009-02-18 21:00:321742 MockWrite data_writes1[] = {
1743 MockWrite("GET / HTTP/1.1\r\n"
1744 "Host: www.google.com\r\n"
1745 "Connection: keep-alive\r\n\r\n"),
1746
1747 // After calling trans->RestartWithAuth(), this is the request we should
1748 // be issuing -- the final header line contains the credentials.
1749 MockWrite("GET / HTTP/1.1\r\n"
1750 "Host: www.google.com\r\n"
1751 "Connection: keep-alive\r\n"
1752 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1753 };
1754
[email protected]2d2697f92009-02-18 21:00:321755 MockRead data_reads1[] = {
1756 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1757 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311758 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321759
1760 // Lastly, the server responds with the actual content.
1761 MockRead("HTTP/1.1 200 OK\r\n"),
1762 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501763 MockRead("Content-Length: 5\r\n\r\n"),
1764 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321765 };
1766
[email protected]2d0a4f92011-05-05 16:38:461767 // An incorrect reconnect would cause this to be read.
1768 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061769 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461770 };
1771
[email protected]31a2bfe2010-02-09 08:03:391772 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1773 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461774 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1775 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071776 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1777 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321778
[email protected]49639fa2011-12-20 23:22:411779 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321780
[email protected]262eec82013-03-19 21:01:361781 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501782 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411783 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421784 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321785
1786 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421787 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321788
[email protected]1c773ea12009-04-28 19:58:421789 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501790 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041791 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321792
[email protected]49639fa2011-12-20 23:22:411793 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321794
[email protected]49639fa2011-12-20 23:22:411795 rv = trans->RestartWithAuth(
1796 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421797 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321798
1799 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421800 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321801
1802 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501803 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321804 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501805 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321806}
1807
1808// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1809// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:021810TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421811 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321812 request.method = "GET";
1813 request.url = GURL("http://www.google.com/");
1814 request.load_flags = 0;
1815
[email protected]bb88e1d32013-05-03 23:11:071816 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271817
[email protected]2d2697f92009-02-18 21:00:321818 MockWrite data_writes1[] = {
1819 MockWrite("GET / HTTP/1.1\r\n"
1820 "Host: www.google.com\r\n"
1821 "Connection: keep-alive\r\n\r\n"),
1822
1823 // After calling trans->RestartWithAuth(), this is the request we should
1824 // be issuing -- the final header line contains the credentials.
1825 MockWrite("GET / HTTP/1.1\r\n"
1826 "Host: www.google.com\r\n"
1827 "Connection: keep-alive\r\n"
1828 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1829 };
1830
1831 // Respond with 5 kb of response body.
1832 std::string large_body_string("Unauthorized");
1833 large_body_string.append(5 * 1024, ' ');
1834 large_body_string.append("\r\n");
1835
1836 MockRead data_reads1[] = {
1837 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1838 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1840 // 5134 = 12 + 5 * 1024 + 2
1841 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061842 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:321843
1844 // Lastly, the server responds with the actual content.
1845 MockRead("HTTP/1.1 200 OK\r\n"),
1846 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501847 MockRead("Content-Length: 5\r\n\r\n"),
1848 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321849 };
1850
[email protected]2d0a4f92011-05-05 16:38:461851 // An incorrect reconnect would cause this to be read.
1852 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061853 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461854 };
1855
[email protected]31a2bfe2010-02-09 08:03:391856 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1857 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461858 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1859 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071860 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1861 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321862
[email protected]49639fa2011-12-20 23:22:411863 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321864
[email protected]262eec82013-03-19 21:01:361865 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501866 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411867 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421868 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321869
1870 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421871 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321872
[email protected]1c773ea12009-04-28 19:58:421873 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501874 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041875 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321876
[email protected]49639fa2011-12-20 23:22:411877 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321878
[email protected]49639fa2011-12-20 23:22:411879 rv = trans->RestartWithAuth(
1880 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421881 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321882
1883 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421884 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321885
1886 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501887 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321888 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501889 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321890}
1891
1892// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:311893// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:021894TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:311895 HttpRequestInfo request;
1896 request.method = "GET";
1897 request.url = GURL("http://www.google.com/");
1898 request.load_flags = 0;
1899
[email protected]bb88e1d32013-05-03 23:11:071900 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271901
[email protected]11203f012009-11-12 23:02:311902 MockWrite data_writes1[] = {
1903 MockWrite("GET / HTTP/1.1\r\n"
1904 "Host: www.google.com\r\n"
1905 "Connection: keep-alive\r\n\r\n"),
1906 // This simulates the seemingly successful write to a closed connection
1907 // if the bug is not fixed.
1908 MockWrite("GET / HTTP/1.1\r\n"
1909 "Host: www.google.com\r\n"
1910 "Connection: keep-alive\r\n"
1911 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1912 };
1913
1914 MockRead data_reads1[] = {
1915 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1916 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1917 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1918 MockRead("Content-Length: 14\r\n\r\n"),
1919 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:061920 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:311921 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:061922 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:311923 };
1924
1925 // After calling trans->RestartWithAuth(), this is the request we should
1926 // be issuing -- the final header line contains the credentials.
1927 MockWrite data_writes2[] = {
1928 MockWrite("GET / HTTP/1.1\r\n"
1929 "Host: www.google.com\r\n"
1930 "Connection: keep-alive\r\n"
1931 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1932 };
1933
1934 // Lastly, the server responds with the actual content.
1935 MockRead data_reads2[] = {
1936 MockRead("HTTP/1.1 200 OK\r\n"),
1937 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501938 MockRead("Content-Length: 5\r\n\r\n"),
1939 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:311940 };
1941
[email protected]31a2bfe2010-02-09 08:03:391942 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1943 data_writes1, arraysize(data_writes1));
1944 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1945 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1947 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:311948
[email protected]49639fa2011-12-20 23:22:411949 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:311950
[email protected]262eec82013-03-19 21:01:361951 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501952 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411953 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:311954 EXPECT_EQ(ERR_IO_PENDING, rv);
1955
1956 rv = callback1.WaitForResult();
1957 EXPECT_EQ(OK, rv);
1958
1959 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501960 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041961 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:311962
[email protected]49639fa2011-12-20 23:22:411963 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:311964
[email protected]49639fa2011-12-20 23:22:411965 rv = trans->RestartWithAuth(
1966 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:311967 EXPECT_EQ(ERR_IO_PENDING, rv);
1968
1969 rv = callback2.WaitForResult();
1970 EXPECT_EQ(OK, rv);
1971
1972 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501973 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:311974 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501975 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:311976}
1977
[email protected]394816e92010-08-03 07:38:591978// Test the request-challenge-retry sequence for basic auth, over a connection
1979// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:021980TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:591981 HttpRequestInfo request;
1982 request.method = "GET";
1983 request.url = GURL("https://www.google.com/");
1984 // when the no authentication data flag is set.
1985 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1986
[email protected]cb9bf6ca2011-01-28 13:15:271987 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:071988 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:201989 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:291990 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071991 session_deps_.net_log = log.bound().net_log();
1992 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271993
[email protected]394816e92010-08-03 07:38:591994 // Since we have proxy, should try to establish tunnel.
1995 MockWrite data_writes1[] = {
1996 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1997 "Host: www.google.com\r\n"
1998 "Proxy-Connection: keep-alive\r\n\r\n"),
1999
2000 // After calling trans->RestartWithAuth(), this is the request we should
2001 // be issuing -- the final header line contains the credentials.
2002 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2003 "Host: www.google.com\r\n"
2004 "Proxy-Connection: keep-alive\r\n"
2005 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2006
2007 MockWrite("GET / HTTP/1.1\r\n"
2008 "Host: www.google.com\r\n"
2009 "Connection: keep-alive\r\n\r\n"),
2010 };
2011
2012 // The proxy responds to the connect with a 407, using a persistent
2013 // connection.
2014 MockRead data_reads1[] = {
2015 // No credentials.
2016 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2017 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2018 MockRead("Proxy-Connection: close\r\n\r\n"),
2019
2020 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2021
2022 MockRead("HTTP/1.1 200 OK\r\n"),
2023 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502024 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062025 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592026 };
2027
2028 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2029 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072030 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062031 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592033
[email protected]49639fa2011-12-20 23:22:412034 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592035
[email protected]262eec82013-03-19 21:01:362036 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502037 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502038
[email protected]49639fa2011-12-20 23:22:412039 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592040 EXPECT_EQ(ERR_IO_PENDING, rv);
2041
2042 rv = callback1.WaitForResult();
2043 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572044 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402045 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592046 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402047 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592048 NetLog::PHASE_NONE);
2049 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402050 entries, pos,
[email protected]394816e92010-08-03 07:38:592051 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2052 NetLog::PHASE_NONE);
2053
2054 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502055 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502056 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592057 EXPECT_EQ(407, response->headers->response_code());
2058 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042059 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592060
[email protected]029c83b62013-01-24 05:28:202061 LoadTimingInfo load_timing_info;
2062 // CONNECT requests and responses are handled at the connect job level, so
2063 // the transaction does not yet have a connection.
2064 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2065
[email protected]49639fa2011-12-20 23:22:412066 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592067
[email protected]49639fa2011-12-20 23:22:412068 rv = trans->RestartWithAuth(
2069 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592070 EXPECT_EQ(ERR_IO_PENDING, rv);
2071
2072 rv = callback2.WaitForResult();
2073 EXPECT_EQ(OK, rv);
2074
2075 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502076 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592077
2078 EXPECT_TRUE(response->headers->IsKeepAlive());
2079 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502080 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592081 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2082
2083 // The password prompt info should not be set.
2084 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502085
[email protected]029c83b62013-01-24 05:28:202086 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2087 TestLoadTimingNotReusedWithPac(load_timing_info,
2088 CONNECT_TIMING_HAS_SSL_TIMES);
2089
[email protected]0b0bf032010-09-21 18:08:502090 trans.reset();
[email protected]102e27c2011-02-23 01:01:312091 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592092}
2093
[email protected]11203f012009-11-12 23:02:312094// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322095// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022096TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272097 HttpRequestInfo request;
2098 request.method = "GET";
2099 request.url = GURL("https://www.google.com/");
2100 // Ensure that proxy authentication is attempted even
2101 // when the no authentication data flag is set.
2102 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2103
[email protected]2d2697f92009-02-18 21:00:322104 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072105 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292106 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072107 session_deps_.net_log = log.bound().net_log();
2108 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322109
[email protected]262eec82013-03-19 21:01:362110 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322112
[email protected]2d2697f92009-02-18 21:00:322113 // Since we have proxy, should try to establish tunnel.
2114 MockWrite data_writes1[] = {
2115 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452116 "Host: www.google.com\r\n"
2117 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322118
2119 // After calling trans->RestartWithAuth(), this is the request we should
2120 // be issuing -- the final header line contains the credentials.
2121 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2122 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452123 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322124 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2125 };
2126
2127 // The proxy responds to the connect with a 407, using a persistent
2128 // connection.
2129 MockRead data_reads1[] = {
2130 // No credentials.
2131 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2132 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2133 MockRead("Content-Length: 10\r\n\r\n"),
2134 MockRead("0123456789"),
2135
2136 // Wrong credentials (wrong password).
2137 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2138 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2139 MockRead("Content-Length: 10\r\n\r\n"),
2140 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062141 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322142 };
2143
[email protected]31a2bfe2010-02-09 08:03:392144 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2145 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072146 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322147
[email protected]49639fa2011-12-20 23:22:412148 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322149
[email protected]49639fa2011-12-20 23:22:412150 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422151 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322152
2153 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422154 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572155 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402156 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392157 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402158 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392159 NetLog::PHASE_NONE);
2160 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402161 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392162 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2163 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322164
[email protected]1c773ea12009-04-28 19:58:422165 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502166 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502167 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322168 EXPECT_TRUE(response->headers->IsKeepAlive());
2169 EXPECT_EQ(407, response->headers->response_code());
2170 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422171 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042172 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322173
[email protected]49639fa2011-12-20 23:22:412174 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322175
2176 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412177 rv = trans->RestartWithAuth(
2178 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422179 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322180
2181 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422182 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322183
2184 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502185 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502186 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322187 EXPECT_TRUE(response->headers->IsKeepAlive());
2188 EXPECT_EQ(407, response->headers->response_code());
2189 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422190 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042191 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132192
[email protected]e60e47a2010-07-14 03:37:182193 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2194 // out of scope.
[email protected]102e27c2011-02-23 01:01:312195 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322196}
2197
[email protected]a8e9b162009-03-12 00:06:442198// Test that we don't read the response body when we fail to establish a tunnel,
2199// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022200TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272201 HttpRequestInfo request;
2202 request.method = "GET";
2203 request.url = GURL("https://www.google.com/");
2204 request.load_flags = 0;
2205
[email protected]a8e9b162009-03-12 00:06:442206 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072207 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442208
[email protected]bb88e1d32013-05-03 23:11:072209 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442210
[email protected]262eec82013-03-19 21:01:362211 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442213
[email protected]a8e9b162009-03-12 00:06:442214 // Since we have proxy, should try to establish tunnel.
2215 MockWrite data_writes[] = {
2216 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452217 "Host: www.google.com\r\n"
2218 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442219 };
2220
2221 // The proxy responds to the connect with a 407.
2222 MockRead data_reads[] = {
2223 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2224 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2225 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062226 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442227 };
2228
[email protected]31a2bfe2010-02-09 08:03:392229 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2230 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072231 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442232
[email protected]49639fa2011-12-20 23:22:412233 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442234
[email protected]49639fa2011-12-20 23:22:412235 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422236 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442237
2238 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422239 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442240
[email protected]1c773ea12009-04-28 19:58:422241 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502242 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442243
2244 EXPECT_TRUE(response->headers->IsKeepAlive());
2245 EXPECT_EQ(407, response->headers->response_code());
2246 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422247 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442248
2249 std::string response_data;
2250 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422251 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182252
2253 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312254 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442255}
2256
[email protected]8fdbcd22010-05-05 02:54:522257// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2258// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022259TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522260 HttpRequestInfo request;
2261 request.method = "GET";
2262 request.url = GURL("http://www.google.com/");
2263 request.load_flags = 0;
2264
[email protected]cb9bf6ca2011-01-28 13:15:272265 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]cb9bf6ca2011-01-28 13:15:272266 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:362267 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:072268 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:272269
[email protected]8fdbcd22010-05-05 02:54:522270 MockWrite data_writes1[] = {
2271 MockWrite("GET / HTTP/1.1\r\n"
2272 "Host: www.google.com\r\n"
2273 "Connection: keep-alive\r\n\r\n"),
2274 };
2275
2276 MockRead data_reads1[] = {
2277 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2278 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2279 // Large content-length -- won't matter, as connection will be reset.
2280 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062281 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522282 };
2283
2284 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2285 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072286 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522287
[email protected]49639fa2011-12-20 23:22:412288 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522289
[email protected]49639fa2011-12-20 23:22:412290 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522291 EXPECT_EQ(ERR_IO_PENDING, rv);
2292
2293 rv = callback.WaitForResult();
2294 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2295}
2296
[email protected]7a67a8152010-11-05 18:31:102297// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2298// through a non-authenticating proxy. The request should fail with
2299// ERR_UNEXPECTED_PROXY_AUTH.
2300// Note that it is impossible to detect if an HTTP server returns a 407 through
2301// a non-authenticating proxy - there is nothing to indicate whether the
2302// response came from the proxy or the server, so it is treated as if the proxy
2303// issued the challenge.
[email protected]23e482282013-06-14 16:08:022304TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232305 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272306 HttpRequestInfo request;
2307 request.method = "GET";
2308 request.url = GURL("https://www.google.com/");
2309
[email protected]bb88e1d32013-05-03 23:11:072310 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292311 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072312 session_deps_.net_log = log.bound().net_log();
2313 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102314
[email protected]7a67a8152010-11-05 18:31:102315 // Since we have proxy, should try to establish tunnel.
2316 MockWrite data_writes1[] = {
2317 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2318 "Host: www.google.com\r\n"
2319 "Proxy-Connection: keep-alive\r\n\r\n"),
2320
2321 MockWrite("GET / HTTP/1.1\r\n"
2322 "Host: www.google.com\r\n"
2323 "Connection: keep-alive\r\n\r\n"),
2324 };
2325
2326 MockRead data_reads1[] = {
2327 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2328
2329 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2330 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2331 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062332 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102333 };
2334
2335 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2336 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072337 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062338 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102340
[email protected]49639fa2011-12-20 23:22:412341 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102342
[email protected]262eec82013-03-19 21:01:362343 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102345
[email protected]49639fa2011-12-20 23:22:412346 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102347 EXPECT_EQ(ERR_IO_PENDING, rv);
2348
2349 rv = callback1.WaitForResult();
2350 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572351 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402352 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102353 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402354 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102355 NetLog::PHASE_NONE);
2356 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402357 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102358 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2359 NetLog::PHASE_NONE);
2360}
[email protected]2df19bb2010-08-25 20:13:462361
[email protected]029c83b62013-01-24 05:28:202362// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022363TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202364 HttpRequestInfo request1;
2365 request1.method = "GET";
2366 request1.url = GURL("https://www.google.com/1");
2367
2368 HttpRequestInfo request2;
2369 request2.method = "GET";
2370 request2.url = GURL("https://www.google.com/2");
2371
2372 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072373 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202374 ProxyService::CreateFixed("PROXY myproxy:70"));
2375 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072376 session_deps_.net_log = log.bound().net_log();
2377 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202378
2379 // Since we have proxy, should try to establish tunnel.
2380 MockWrite data_writes1[] = {
2381 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2382 "Host: www.google.com\r\n"
2383 "Proxy-Connection: keep-alive\r\n\r\n"),
2384
2385 MockWrite("GET /1 HTTP/1.1\r\n"
2386 "Host: www.google.com\r\n"
2387 "Connection: keep-alive\r\n\r\n"),
2388
2389 MockWrite("GET /2 HTTP/1.1\r\n"
2390 "Host: www.google.com\r\n"
2391 "Connection: keep-alive\r\n\r\n"),
2392 };
2393
2394 // The proxy responds to the connect with a 407, using a persistent
2395 // connection.
2396 MockRead data_reads1[] = {
2397 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2398
2399 MockRead("HTTP/1.1 200 OK\r\n"),
2400 MockRead("Content-Length: 1\r\n\r\n"),
2401 MockRead(SYNCHRONOUS, "1"),
2402
2403 MockRead("HTTP/1.1 200 OK\r\n"),
2404 MockRead("Content-Length: 2\r\n\r\n"),
2405 MockRead(SYNCHRONOUS, "22"),
2406 };
2407
2408 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2409 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072410 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202411 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202413
2414 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362415 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502416 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202417
2418 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2419 EXPECT_EQ(ERR_IO_PENDING, rv);
2420
2421 rv = callback1.WaitForResult();
2422 EXPECT_EQ(OK, rv);
2423
2424 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2425 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502426 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202427 EXPECT_EQ(1, response1->headers->GetContentLength());
2428
2429 LoadTimingInfo load_timing_info1;
2430 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2431 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2432
2433 trans1.reset();
2434
2435 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362436 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502437 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202438
2439 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2440 EXPECT_EQ(ERR_IO_PENDING, rv);
2441
2442 rv = callback2.WaitForResult();
2443 EXPECT_EQ(OK, rv);
2444
2445 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2446 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502447 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202448 EXPECT_EQ(2, response2->headers->GetContentLength());
2449
2450 LoadTimingInfo load_timing_info2;
2451 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2452 TestLoadTimingReused(load_timing_info2);
2453
2454 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2455
2456 trans2.reset();
2457 session->CloseAllConnections();
2458}
2459
2460// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022461TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202462 HttpRequestInfo request1;
2463 request1.method = "GET";
2464 request1.url = GURL("https://www.google.com/1");
2465
2466 HttpRequestInfo request2;
2467 request2.method = "GET";
2468 request2.url = GURL("https://www.google.com/2");
2469
2470 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072471 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202472 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2473 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072474 session_deps_.net_log = log.bound().net_log();
2475 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202476
2477 // Since we have proxy, should try to establish tunnel.
2478 MockWrite data_writes1[] = {
2479 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2480 "Host: www.google.com\r\n"
2481 "Proxy-Connection: keep-alive\r\n\r\n"),
2482
2483 MockWrite("GET /1 HTTP/1.1\r\n"
2484 "Host: www.google.com\r\n"
2485 "Connection: keep-alive\r\n\r\n"),
2486
2487 MockWrite("GET /2 HTTP/1.1\r\n"
2488 "Host: www.google.com\r\n"
2489 "Connection: keep-alive\r\n\r\n"),
2490 };
2491
2492 // The proxy responds to the connect with a 407, using a persistent
2493 // connection.
2494 MockRead data_reads1[] = {
2495 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2496
2497 MockRead("HTTP/1.1 200 OK\r\n"),
2498 MockRead("Content-Length: 1\r\n\r\n"),
2499 MockRead(SYNCHRONOUS, "1"),
2500
2501 MockRead("HTTP/1.1 200 OK\r\n"),
2502 MockRead("Content-Length: 2\r\n\r\n"),
2503 MockRead(SYNCHRONOUS, "22"),
2504 };
2505
2506 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2507 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072508 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202509 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072510 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202511
2512 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362513 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502514 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202515
2516 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2517 EXPECT_EQ(ERR_IO_PENDING, rv);
2518
2519 rv = callback1.WaitForResult();
2520 EXPECT_EQ(OK, rv);
2521
2522 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2523 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502524 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202525 EXPECT_EQ(1, response1->headers->GetContentLength());
2526
2527 LoadTimingInfo load_timing_info1;
2528 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2529 TestLoadTimingNotReusedWithPac(load_timing_info1,
2530 CONNECT_TIMING_HAS_SSL_TIMES);
2531
2532 trans1.reset();
2533
2534 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362535 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202537
2538 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2539 EXPECT_EQ(ERR_IO_PENDING, rv);
2540
2541 rv = callback2.WaitForResult();
2542 EXPECT_EQ(OK, rv);
2543
2544 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2545 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502546 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202547 EXPECT_EQ(2, response2->headers->GetContentLength());
2548
2549 LoadTimingInfo load_timing_info2;
2550 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2551 TestLoadTimingReusedWithPac(load_timing_info2);
2552
2553 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2554
2555 trans2.reset();
2556 session->CloseAllConnections();
2557}
2558
[email protected]2df19bb2010-08-25 20:13:462559// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022560TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272561 HttpRequestInfo request;
2562 request.method = "GET";
2563 request.url = GURL("http://www.google.com/");
2564
[email protected]2df19bb2010-08-25 20:13:462565 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072566 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112567 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292568 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072569 session_deps_.net_log = log.bound().net_log();
2570 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462571
[email protected]2df19bb2010-08-25 20:13:462572 // Since we have proxy, should use full url
2573 MockWrite data_writes1[] = {
2574 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2575 "Host: www.google.com\r\n"
2576 "Proxy-Connection: keep-alive\r\n\r\n"),
2577 };
2578
2579 MockRead data_reads1[] = {
2580 MockRead("HTTP/1.1 200 OK\r\n"),
2581 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2582 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062583 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462584 };
2585
2586 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2587 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072588 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062589 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462591
[email protected]49639fa2011-12-20 23:22:412592 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462593
[email protected]262eec82013-03-19 21:01:362594 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502596
[email protected]49639fa2011-12-20 23:22:412597 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462598 EXPECT_EQ(ERR_IO_PENDING, rv);
2599
2600 rv = callback1.WaitForResult();
2601 EXPECT_EQ(OK, rv);
2602
[email protected]58e32bb2013-01-21 18:23:252603 LoadTimingInfo load_timing_info;
2604 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2605 TestLoadTimingNotReused(load_timing_info,
2606 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2607
[email protected]2df19bb2010-08-25 20:13:462608 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502609 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462610
2611 EXPECT_TRUE(response->headers->IsKeepAlive());
2612 EXPECT_EQ(200, response->headers->response_code());
2613 EXPECT_EQ(100, response->headers->GetContentLength());
2614 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2615
2616 // The password prompt info should not be set.
2617 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2618}
2619
[email protected]7642b5ae2010-09-01 20:55:172620// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022621TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272622 HttpRequestInfo request;
2623 request.method = "GET";
2624 request.url = GURL("http://www.google.com/");
2625 request.load_flags = 0;
2626
[email protected]7642b5ae2010-09-01 20:55:172627 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072628 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112629 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292630 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072631 session_deps_.net_log = log.bound().net_log();
2632 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172633
[email protected]7642b5ae2010-09-01 20:55:172634 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462635 scoped_ptr<SpdyFrame> req(
2636 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172637 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2638
[email protected]23e482282013-06-14 16:08:022639 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2640 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172641 MockRead spdy_reads[] = {
2642 CreateMockRead(*resp),
2643 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062644 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172645 };
2646
[email protected]dd54bd82012-07-19 23:44:572647 DelayedSocketData spdy_data(
2648 1, // wait for one write to finish before reading.
2649 spdy_reads, arraysize(spdy_reads),
2650 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072651 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172652
[email protected]8ddf8322012-02-23 18:08:062653 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022654 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072655 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172656
[email protected]49639fa2011-12-20 23:22:412657 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172658
[email protected]262eec82013-03-19 21:01:362659 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502661
[email protected]49639fa2011-12-20 23:22:412662 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172663 EXPECT_EQ(ERR_IO_PENDING, rv);
2664
2665 rv = callback1.WaitForResult();
2666 EXPECT_EQ(OK, rv);
2667
[email protected]58e32bb2013-01-21 18:23:252668 LoadTimingInfo load_timing_info;
2669 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2670 TestLoadTimingNotReused(load_timing_info,
2671 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2672
[email protected]7642b5ae2010-09-01 20:55:172673 const HttpResponseInfo* response = trans->GetResponseInfo();
2674 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502675 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172676 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2677
2678 std::string response_data;
2679 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232680 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172681}
2682
[email protected]dc7bd1c52010-11-12 00:01:132683// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022684TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272685 HttpRequestInfo request;
2686 request.method = "GET";
2687 request.url = GURL("http://www.google.com/");
2688 request.load_flags = 0;
2689
[email protected]79cb5c12011-09-12 13:12:042690 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072691 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042692 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292693 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072694 session_deps_.net_log = log.bound().net_log();
2695 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132696
[email protected]dc7bd1c52010-11-12 00:01:132697 // The first request will be a bare GET, the second request will be a
2698 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192699 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462700 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132701 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462702 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132703 };
[email protected]ff98d7f02012-03-22 21:44:192704 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462705 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2706 arraysize(kExtraAuthorizationHeaders) / 2,
2707 false,
2708 3,
2709 LOWEST,
2710 false));
[email protected]dc7bd1c52010-11-12 00:01:132711 MockWrite spdy_writes[] = {
2712 CreateMockWrite(*req_get, 1),
2713 CreateMockWrite(*req_get_authorization, 4),
2714 };
2715
2716 // The first response is a 407 proxy authentication challenge, and the second
2717 // response will be a 200 response since the second request includes a valid
2718 // Authorization header.
2719 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462720 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132721 };
[email protected]ff98d7f02012-03-22 21:44:192722 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022723 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132724 "407 Proxy Authentication Required",
2725 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2726 1));
[email protected]ff98d7f02012-03-22 21:44:192727 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022728 spdy_util_.ConstructSpdyBodyFrame(1, true));
2729 scoped_ptr<SpdyFrame> resp_data(
2730 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2731 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132732 MockRead spdy_reads[] = {
2733 CreateMockRead(*resp_authentication, 2),
2734 CreateMockRead(*body_authentication, 3),
2735 CreateMockRead(*resp_data, 5),
2736 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:062737 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:132738 };
2739
[email protected]dd54bd82012-07-19 23:44:572740 OrderedSocketData data(
2741 spdy_reads, arraysize(spdy_reads),
2742 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072743 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:132744
[email protected]8ddf8322012-02-23 18:08:062745 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022746 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072747 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:132748
[email protected]49639fa2011-12-20 23:22:412749 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132750
[email protected]262eec82013-03-19 21:01:362751 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502752 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:132753
[email protected]49639fa2011-12-20 23:22:412754 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:132755 EXPECT_EQ(ERR_IO_PENDING, rv);
2756
2757 rv = callback1.WaitForResult();
2758 EXPECT_EQ(OK, rv);
2759
2760 const HttpResponseInfo* const response = trans->GetResponseInfo();
2761
2762 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502763 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132764 EXPECT_EQ(407, response->headers->response_code());
2765 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042766 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132767
[email protected]49639fa2011-12-20 23:22:412768 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132769
[email protected]49639fa2011-12-20 23:22:412770 rv = trans->RestartWithAuth(
2771 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:132772 EXPECT_EQ(ERR_IO_PENDING, rv);
2773
2774 rv = callback2.WaitForResult();
2775 EXPECT_EQ(OK, rv);
2776
2777 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2778
2779 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:502780 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132781 EXPECT_EQ(200, response_restart->headers->response_code());
2782 // The password prompt info should not be set.
2783 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2784}
2785
[email protected]d9da5fe2010-10-13 22:37:162786// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:022787TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272788 HttpRequestInfo request;
2789 request.method = "GET";
2790 request.url = GURL("https://www.google.com/");
2791 request.load_flags = 0;
2792
[email protected]d9da5fe2010-10-13 22:37:162793 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072794 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112795 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292796 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072797 session_deps_.net_log = log.bound().net_log();
2798 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162799
[email protected]262eec82013-03-19 21:01:362800 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502801 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162802
[email protected]d9da5fe2010-10-13 22:37:162803 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542804 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2805 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162806 // fetch https://www.google.com/ via HTTP
2807
2808 const char get[] = "GET / HTTP/1.1\r\n"
2809 "Host: www.google.com\r\n"
2810 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192811 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:022812 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2813 scoped_ptr<SpdyFrame> conn_resp(
2814 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162815 const char resp[] = "HTTP/1.1 200 OK\r\n"
2816 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192817 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022818 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:192819 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:022820 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:192821 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:202822 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:042823
2824 MockWrite spdy_writes[] = {
2825 CreateMockWrite(*connect, 1),
2826 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:462827 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:042828 };
2829
[email protected]d9da5fe2010-10-13 22:37:162830 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062831 CreateMockRead(*conn_resp, 2, ASYNC),
2832 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2833 CreateMockRead(*wrapped_body, 6, ASYNC),
2834 CreateMockRead(*wrapped_body, 7, ASYNC),
2835 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162836 };
2837
[email protected]dd54bd82012-07-19 23:44:572838 OrderedSocketData spdy_data(
2839 spdy_reads, arraysize(spdy_reads),
2840 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072841 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162842
[email protected]8ddf8322012-02-23 18:08:062843 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022844 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062846 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:162847 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:462848 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:072849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162850
[email protected]49639fa2011-12-20 23:22:412851 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162852
[email protected]49639fa2011-12-20 23:22:412853 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162854 EXPECT_EQ(ERR_IO_PENDING, rv);
2855
2856 rv = callback1.WaitForResult();
2857 EXPECT_EQ(OK, rv);
2858
[email protected]58e32bb2013-01-21 18:23:252859 LoadTimingInfo load_timing_info;
2860 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2861 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2862
[email protected]d9da5fe2010-10-13 22:37:162863 const HttpResponseInfo* response = trans->GetResponseInfo();
2864 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502865 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162866 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2867
2868 std::string response_data;
2869 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2870 EXPECT_EQ("1234567890", response_data);
2871}
2872
2873// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:022874TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:272875 HttpRequestInfo request;
2876 request.method = "GET";
2877 request.url = GURL("https://www.google.com/");
2878 request.load_flags = 0;
2879
[email protected]d9da5fe2010-10-13 22:37:162880 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072881 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112882 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292883 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072884 session_deps_.net_log = log.bound().net_log();
2885 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162886
[email protected]262eec82013-03-19 21:01:362887 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502888 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162889
[email protected]d9da5fe2010-10-13 22:37:162890 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542891 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2892 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162893 // fetch https://www.google.com/ via SPDY
2894 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:462895 scoped_ptr<SpdyFrame> get(
2896 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:022897 scoped_ptr<SpdyFrame> wrapped_get(
2898 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
2899 scoped_ptr<SpdyFrame> conn_resp(
2900 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2901 scoped_ptr<SpdyFrame> get_resp(
2902 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:192903 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022904 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
2905 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2906 scoped_ptr<SpdyFrame> wrapped_body(
2907 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:192908 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:202909 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:192910 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:202911 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:042912
2913 MockWrite spdy_writes[] = {
2914 CreateMockWrite(*connect, 1),
2915 CreateMockWrite(*wrapped_get, 3),
2916 CreateMockWrite(*window_update_get_resp, 5),
2917 CreateMockWrite(*window_update_body, 7),
2918 };
2919
[email protected]d9da5fe2010-10-13 22:37:162920 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062921 CreateMockRead(*conn_resp, 2, ASYNC),
2922 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2923 CreateMockRead(*wrapped_body, 6, ASYNC),
2924 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162925 };
2926
[email protected]dd54bd82012-07-19 23:44:572927 OrderedSocketData spdy_data(
2928 spdy_reads, arraysize(spdy_reads),
2929 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072930 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162931
[email protected]8ddf8322012-02-23 18:08:062932 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022933 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062935 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022936 ssl2.SetNextProto(GetParam());
2937 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:072938 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162939
[email protected]49639fa2011-12-20 23:22:412940 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162941
[email protected]49639fa2011-12-20 23:22:412942 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162943 EXPECT_EQ(ERR_IO_PENDING, rv);
2944
2945 rv = callback1.WaitForResult();
2946 EXPECT_EQ(OK, rv);
2947
[email protected]58e32bb2013-01-21 18:23:252948 LoadTimingInfo load_timing_info;
2949 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2950 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2951
[email protected]d9da5fe2010-10-13 22:37:162952 const HttpResponseInfo* response = trans->GetResponseInfo();
2953 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502954 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162955 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2956
2957 std::string response_data;
2958 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232959 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:162960}
2961
2962// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022963TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:272964 HttpRequestInfo request;
2965 request.method = "GET";
2966 request.url = GURL("https://www.google.com/");
2967 request.load_flags = 0;
2968
[email protected]d9da5fe2010-10-13 22:37:162969 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072970 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112971 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292972 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072973 session_deps_.net_log = log.bound().net_log();
2974 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162975
[email protected]262eec82013-03-19 21:01:362976 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162978
[email protected]d9da5fe2010-10-13 22:37:162979 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542980 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2981 LOWEST));
[email protected]c10b20852013-05-15 21:29:202982 scoped_ptr<SpdyFrame> get(
2983 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:162984
2985 MockWrite spdy_writes[] = {
2986 CreateMockWrite(*connect, 1),
2987 CreateMockWrite(*get, 3),
2988 };
2989
[email protected]23e482282013-06-14 16:08:022990 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
2991 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:162992 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062993 CreateMockRead(*resp, 2, ASYNC),
2994 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:162995 };
2996
[email protected]dd54bd82012-07-19 23:44:572997 OrderedSocketData spdy_data(
2998 spdy_reads, arraysize(spdy_reads),
2999 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073000 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163001
[email protected]8ddf8322012-02-23 18:08:063002 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023003 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073004 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063005 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023006 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073007 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163008
[email protected]49639fa2011-12-20 23:22:413009 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163010
[email protected]49639fa2011-12-20 23:22:413011 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163012 EXPECT_EQ(ERR_IO_PENDING, rv);
3013
3014 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173015 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163016
[email protected]4eddbc732012-08-09 05:40:173017 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163018}
3019
[email protected]f6c63db52013-02-02 00:35:223020// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3021// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023022TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223023 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3024 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073025 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223026 "https://proxy:70"));
3027 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073028 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223029 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073030 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223031
3032 HttpRequestInfo request1;
3033 request1.method = "GET";
3034 request1.url = GURL("https://www.google.com/");
3035 request1.load_flags = 0;
3036
3037 HttpRequestInfo request2;
3038 request2.method = "GET";
3039 request2.url = GURL("https://news.google.com/");
3040 request2.load_flags = 0;
3041
3042 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543043 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3044 LOWEST));
[email protected]23e482282013-06-14 16:08:023045 scoped_ptr<SpdyFrame> conn_resp1(
3046 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223047
3048 // Fetch https://www.google.com/ via HTTP.
3049 const char get1[] = "GET / HTTP/1.1\r\n"
3050 "Host: www.google.com\r\n"
3051 "Connection: keep-alive\r\n\r\n";
3052 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023053 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223054 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3055 "Content-Length: 1\r\n\r\n";
3056 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023057 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3058 scoped_ptr<SpdyFrame> wrapped_body1(
3059 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223060 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203061 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223062
3063 // CONNECT to news.google.com:443 via SPDY.
3064 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023065 spdy_util_.GetMethodKey(), "CONNECT",
3066 spdy_util_.GetPathKey(), "news.google.com:443",
3067 spdy_util_.GetHostKey(), "news.google.com",
3068 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223069 };
3070 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233071 spdy_util_.ConstructSpdyControlFrame(NULL,
3072 0,
3073 /*compressed*/ false,
3074 3,
3075 LOWEST,
3076 SYN_STREAM,
3077 CONTROL_FLAG_NONE,
3078 kConnectHeaders2,
3079 arraysize(kConnectHeaders2),
3080 0));
[email protected]23e482282013-06-14 16:08:023081 scoped_ptr<SpdyFrame> conn_resp2(
3082 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223083
3084 // Fetch https://news.google.com/ via HTTP.
3085 const char get2[] = "GET / HTTP/1.1\r\n"
3086 "Host: news.google.com\r\n"
3087 "Connection: keep-alive\r\n\r\n";
3088 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023089 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223090 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3091 "Content-Length: 2\r\n\r\n";
3092 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023093 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223094 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023095 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223096
3097 MockWrite spdy_writes[] = {
3098 CreateMockWrite(*connect1, 0),
3099 CreateMockWrite(*wrapped_get1, 2),
3100 CreateMockWrite(*connect2, 5),
3101 CreateMockWrite(*wrapped_get2, 7),
3102 };
3103
3104 MockRead spdy_reads[] = {
3105 CreateMockRead(*conn_resp1, 1, ASYNC),
3106 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3107 CreateMockRead(*wrapped_body1, 4, ASYNC),
3108 CreateMockRead(*conn_resp2, 6, ASYNC),
3109 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3110 CreateMockRead(*wrapped_body2, 9, ASYNC),
3111 MockRead(ASYNC, 0, 10),
3112 };
3113
3114 DeterministicSocketData spdy_data(
3115 spdy_reads, arraysize(spdy_reads),
3116 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073117 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223118
3119 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023120 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073121 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223122 SSLSocketDataProvider ssl2(ASYNC, OK);
3123 ssl2.was_npn_negotiated = false;
3124 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073125 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223126 SSLSocketDataProvider ssl3(ASYNC, OK);
3127 ssl3.was_npn_negotiated = false;
3128 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073129 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223130
3131 TestCompletionCallback callback;
3132
[email protected]262eec82013-03-19 21:01:363133 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503134 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223135 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3136 EXPECT_EQ(ERR_IO_PENDING, rv);
3137 // The first connect and request, each of their responses, and the body.
3138 spdy_data.RunFor(5);
3139
3140 rv = callback.WaitForResult();
3141 EXPECT_EQ(OK, rv);
3142
3143 LoadTimingInfo load_timing_info;
3144 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3145 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3146
3147 const HttpResponseInfo* response = trans->GetResponseInfo();
3148 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503149 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223150 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3151
3152 std::string response_data;
3153 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503154 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223155
[email protected]262eec82013-03-19 21:01:363156 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503157 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223158 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3159 EXPECT_EQ(ERR_IO_PENDING, rv);
3160
3161 // The second connect and request, each of their responses, and the body.
3162 spdy_data.RunFor(5);
3163 rv = callback.WaitForResult();
3164 EXPECT_EQ(OK, rv);
3165
3166 LoadTimingInfo load_timing_info2;
3167 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3168 // Even though the SPDY connection is reused, a new tunnelled connection has
3169 // to be created, so the socket's load timing looks like a fresh connection.
3170 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3171
3172 // The requests should have different IDs, since they each are using their own
3173 // separate stream.
3174 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3175
[email protected]90499482013-06-01 00:39:503176 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223177}
3178
3179// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3180// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023181TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223182 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3183 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073184 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223185 "https://proxy:70"));
3186 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073187 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223188 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073189 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223190
3191 HttpRequestInfo request1;
3192 request1.method = "GET";
3193 request1.url = GURL("https://www.google.com/");
3194 request1.load_flags = 0;
3195
3196 HttpRequestInfo request2;
3197 request2.method = "GET";
3198 request2.url = GURL("https://www.google.com/2");
3199 request2.load_flags = 0;
3200
3201 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543202 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3203 LOWEST));
[email protected]23e482282013-06-14 16:08:023204 scoped_ptr<SpdyFrame> conn_resp1(
3205 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223206
3207 // Fetch https://www.google.com/ via HTTP.
3208 const char get1[] = "GET / HTTP/1.1\r\n"
3209 "Host: www.google.com\r\n"
3210 "Connection: keep-alive\r\n\r\n";
3211 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023212 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223213 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3214 "Content-Length: 1\r\n\r\n";
3215 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023216 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3217 scoped_ptr<SpdyFrame> wrapped_body1(
3218 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223219 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203220 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223221
3222 // Fetch https://www.google.com/2 via HTTP.
3223 const char get2[] = "GET /2 HTTP/1.1\r\n"
3224 "Host: www.google.com\r\n"
3225 "Connection: keep-alive\r\n\r\n";
3226 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023227 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223228 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3229 "Content-Length: 2\r\n\r\n";
3230 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023231 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223232 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023233 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223234
3235 MockWrite spdy_writes[] = {
3236 CreateMockWrite(*connect1, 0),
3237 CreateMockWrite(*wrapped_get1, 2),
3238 CreateMockWrite(*wrapped_get2, 5),
3239 };
3240
3241 MockRead spdy_reads[] = {
3242 CreateMockRead(*conn_resp1, 1, ASYNC),
3243 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3244 CreateMockRead(*wrapped_body1, 4, ASYNC),
3245 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3246 CreateMockRead(*wrapped_body2, 7, ASYNC),
3247 MockRead(ASYNC, 0, 8),
3248 };
3249
3250 DeterministicSocketData spdy_data(
3251 spdy_reads, arraysize(spdy_reads),
3252 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073253 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223254
3255 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023256 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073257 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223258 SSLSocketDataProvider ssl2(ASYNC, OK);
3259 ssl2.was_npn_negotiated = false;
3260 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073261 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223262
3263 TestCompletionCallback callback;
3264
[email protected]262eec82013-03-19 21:01:363265 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503266 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223267 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3268 EXPECT_EQ(ERR_IO_PENDING, rv);
3269 // The first connect and request, each of their responses, and the body.
3270 spdy_data.RunFor(5);
3271
3272 rv = callback.WaitForResult();
3273 EXPECT_EQ(OK, rv);
3274
3275 LoadTimingInfo load_timing_info;
3276 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3277 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3278
3279 const HttpResponseInfo* response = trans->GetResponseInfo();
3280 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503281 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223282 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3283
3284 std::string response_data;
3285 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503286 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223287 trans.reset();
3288
[email protected]262eec82013-03-19 21:01:363289 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503290 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223291 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3292 EXPECT_EQ(ERR_IO_PENDING, rv);
3293
3294 // The second request, response, and body. There should not be a second
3295 // connect.
3296 spdy_data.RunFor(3);
3297 rv = callback.WaitForResult();
3298 EXPECT_EQ(OK, rv);
3299
3300 LoadTimingInfo load_timing_info2;
3301 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3302 TestLoadTimingReused(load_timing_info2);
3303
3304 // The requests should have the same ID.
3305 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3306
[email protected]90499482013-06-01 00:39:503307 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223308}
3309
3310// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3311// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023312TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223313 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3314 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073315 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223316 "https://proxy:70"));
3317 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073318 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223319 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073320 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223321
3322 HttpRequestInfo request1;
3323 request1.method = "GET";
3324 request1.url = GURL("http://www.google.com/");
3325 request1.load_flags = 0;
3326
3327 HttpRequestInfo request2;
3328 request2.method = "GET";
3329 request2.url = GURL("http://news.google.com/");
3330 request2.load_flags = 0;
3331
3332 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023333 scoped_ptr<SpdyHeaderBlock> headers(
3334 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233335 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023336 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3337 scoped_ptr<SpdyFrame> get_resp1(
3338 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3339 scoped_ptr<SpdyFrame> body1(
3340 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223341
3342 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023343 scoped_ptr<SpdyHeaderBlock> headers2(
3344 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233345 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023346 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3347 scoped_ptr<SpdyFrame> get_resp2(
3348 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3349 scoped_ptr<SpdyFrame> body2(
3350 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223351
3352 MockWrite spdy_writes[] = {
3353 CreateMockWrite(*get1, 0),
3354 CreateMockWrite(*get2, 3),
3355 };
3356
3357 MockRead spdy_reads[] = {
3358 CreateMockRead(*get_resp1, 1, ASYNC),
3359 CreateMockRead(*body1, 2, ASYNC),
3360 CreateMockRead(*get_resp2, 4, ASYNC),
3361 CreateMockRead(*body2, 5, ASYNC),
3362 MockRead(ASYNC, 0, 6),
3363 };
3364
3365 DeterministicSocketData spdy_data(
3366 spdy_reads, arraysize(spdy_reads),
3367 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073368 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223369
3370 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023371 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073372 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223373
3374 TestCompletionCallback callback;
3375
[email protected]262eec82013-03-19 21:01:363376 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223378 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3379 EXPECT_EQ(ERR_IO_PENDING, rv);
3380 spdy_data.RunFor(2);
3381
3382 rv = callback.WaitForResult();
3383 EXPECT_EQ(OK, rv);
3384
3385 LoadTimingInfo load_timing_info;
3386 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3387 TestLoadTimingNotReused(load_timing_info,
3388 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3389
3390 const HttpResponseInfo* response = trans->GetResponseInfo();
3391 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503392 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223393 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3394
3395 std::string response_data;
3396 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503397 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223398 spdy_data.RunFor(1);
3399 EXPECT_EQ(1, callback.WaitForResult());
3400 // Delete the first request, so the second one can reuse the socket.
3401 trans.reset();
3402
[email protected]262eec82013-03-19 21:01:363403 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223405 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3406 EXPECT_EQ(ERR_IO_PENDING, rv);
3407
3408 spdy_data.RunFor(2);
3409 rv = callback.WaitForResult();
3410 EXPECT_EQ(OK, rv);
3411
3412 LoadTimingInfo load_timing_info2;
3413 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3414 TestLoadTimingReused(load_timing_info2);
3415
3416 // The requests should have the same ID.
3417 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3418
[email protected]90499482013-06-01 00:39:503419 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223420 spdy_data.RunFor(1);
3421 EXPECT_EQ(2, callback.WaitForResult());
3422}
3423
[email protected]2df19bb2010-08-25 20:13:463424// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023425TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463426 HttpRequestInfo request;
3427 request.method = "GET";
3428 request.url = GURL("http://www.google.com/");
3429 // when the no authentication data flag is set.
3430 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3431
[email protected]79cb5c12011-09-12 13:12:043432 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073433 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043434 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293435 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073436 session_deps_.net_log = log.bound().net_log();
3437 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273438
[email protected]2df19bb2010-08-25 20:13:463439 // Since we have proxy, should use full url
3440 MockWrite data_writes1[] = {
3441 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3442 "Host: www.google.com\r\n"
3443 "Proxy-Connection: keep-alive\r\n\r\n"),
3444
3445 // After calling trans->RestartWithAuth(), this is the request we should
3446 // be issuing -- the final header line contains the credentials.
3447 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3448 "Host: www.google.com\r\n"
3449 "Proxy-Connection: keep-alive\r\n"
3450 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3451 };
3452
3453 // The proxy responds to the GET with a 407, using a persistent
3454 // connection.
3455 MockRead data_reads1[] = {
3456 // No credentials.
3457 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3458 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3459 MockRead("Proxy-Connection: keep-alive\r\n"),
3460 MockRead("Content-Length: 0\r\n\r\n"),
3461
3462 MockRead("HTTP/1.1 200 OK\r\n"),
3463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3464 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063465 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463466 };
3467
3468 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3469 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063471 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463473
[email protected]49639fa2011-12-20 23:22:413474 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463475
[email protected]262eec82013-03-19 21:01:363476 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503477 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503478
[email protected]49639fa2011-12-20 23:22:413479 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463480 EXPECT_EQ(ERR_IO_PENDING, rv);
3481
3482 rv = callback1.WaitForResult();
3483 EXPECT_EQ(OK, rv);
3484
[email protected]58e32bb2013-01-21 18:23:253485 LoadTimingInfo load_timing_info;
3486 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3487 TestLoadTimingNotReused(load_timing_info,
3488 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3489
[email protected]2df19bb2010-08-25 20:13:463490 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503491 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503492 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463493 EXPECT_EQ(407, response->headers->response_code());
3494 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043495 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463496
[email protected]49639fa2011-12-20 23:22:413497 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463498
[email protected]49639fa2011-12-20 23:22:413499 rv = trans->RestartWithAuth(
3500 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463501 EXPECT_EQ(ERR_IO_PENDING, rv);
3502
3503 rv = callback2.WaitForResult();
3504 EXPECT_EQ(OK, rv);
3505
[email protected]58e32bb2013-01-21 18:23:253506 load_timing_info = LoadTimingInfo();
3507 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3508 // Retrying with HTTP AUTH is considered to be reusing a socket.
3509 TestLoadTimingReused(load_timing_info);
3510
[email protected]2df19bb2010-08-25 20:13:463511 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503512 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463513
3514 EXPECT_TRUE(response->headers->IsKeepAlive());
3515 EXPECT_EQ(200, response->headers->response_code());
3516 EXPECT_EQ(100, response->headers->GetContentLength());
3517 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3518
3519 // The password prompt info should not be set.
3520 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3521}
3522
[email protected]23e482282013-06-14 16:08:023523void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083524 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423525 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083526 request.method = "GET";
3527 request.url = GURL("https://www.google.com/");
3528 request.load_flags = 0;
3529
[email protected]cb9bf6ca2011-01-28 13:15:273530 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073531 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:273532
[email protected]bb88e1d32013-05-03 23:11:073533 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273534
[email protected]c744cf22009-02-27 07:28:083535 // Since we have proxy, should try to establish tunnel.
3536 MockWrite data_writes[] = {
3537 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453538 "Host: www.google.com\r\n"
3539 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083540 };
3541
3542 MockRead data_reads[] = {
3543 status,
3544 MockRead("Content-Length: 10\r\n\r\n"),
3545 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063546 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083547 };
3548
[email protected]31a2bfe2010-02-09 08:03:393549 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3550 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073551 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083552
[email protected]49639fa2011-12-20 23:22:413553 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083554
[email protected]262eec82013-03-19 21:01:363555 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503557
[email protected]49639fa2011-12-20 23:22:413558 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423559 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083560
3561 rv = callback.WaitForResult();
3562 EXPECT_EQ(expected_status, rv);
3563}
3564
[email protected]23e482282013-06-14 16:08:023565void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233566 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083567 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423568 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083569}
3570
[email protected]23e482282013-06-14 16:08:023571TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083572 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3573}
3574
[email protected]23e482282013-06-14 16:08:023575TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083576 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3577}
3578
[email protected]23e482282013-06-14 16:08:023579TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083580 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3581}
3582
[email protected]23e482282013-06-14 16:08:023583TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083584 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3585}
3586
[email protected]23e482282013-06-14 16:08:023587TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083588 ConnectStatusHelper(
3589 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3590}
3591
[email protected]23e482282013-06-14 16:08:023592TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083593 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3594}
3595
[email protected]23e482282013-06-14 16:08:023596TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083597 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3598}
3599
[email protected]23e482282013-06-14 16:08:023600TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083601 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3602}
3603
[email protected]23e482282013-06-14 16:08:023604TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083605 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3606}
3607
[email protected]23e482282013-06-14 16:08:023608TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083609 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3610}
3611
[email protected]23e482282013-06-14 16:08:023612TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083613 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3614}
3615
[email protected]23e482282013-06-14 16:08:023616TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083617 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3618}
3619
[email protected]23e482282013-06-14 16:08:023620TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083621 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3622}
3623
[email protected]23e482282013-06-14 16:08:023624TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083625 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3626}
3627
[email protected]23e482282013-06-14 16:08:023628TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083629 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3630}
3631
[email protected]23e482282013-06-14 16:08:023632TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083633 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3634}
3635
[email protected]23e482282013-06-14 16:08:023636TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083637 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3638}
3639
[email protected]23e482282013-06-14 16:08:023640TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083641 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3642}
3643
[email protected]23e482282013-06-14 16:08:023644TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083645 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3646}
3647
[email protected]23e482282013-06-14 16:08:023648TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083649 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3650}
3651
[email protected]23e482282013-06-14 16:08:023652TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083653 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3654}
3655
[email protected]23e482282013-06-14 16:08:023656TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083657 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3658}
3659
[email protected]23e482282013-06-14 16:08:023660TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083661 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3662}
3663
[email protected]23e482282013-06-14 16:08:023664TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083665 ConnectStatusHelperWithExpectedStatus(
3666 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543667 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083668}
3669
[email protected]23e482282013-06-14 16:08:023670TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083671 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3672}
3673
[email protected]23e482282013-06-14 16:08:023674TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083675 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3676}
3677
[email protected]23e482282013-06-14 16:08:023678TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083679 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3680}
3681
[email protected]23e482282013-06-14 16:08:023682TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083683 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3684}
3685
[email protected]23e482282013-06-14 16:08:023686TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083687 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3688}
3689
[email protected]23e482282013-06-14 16:08:023690TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083691 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3692}
3693
[email protected]23e482282013-06-14 16:08:023694TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083695 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3696}
3697
[email protected]23e482282013-06-14 16:08:023698TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083699 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3700}
3701
[email protected]23e482282013-06-14 16:08:023702TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083703 ConnectStatusHelper(
3704 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3705}
3706
[email protected]23e482282013-06-14 16:08:023707TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083708 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3709}
3710
[email protected]23e482282013-06-14 16:08:023711TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083712 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3713}
3714
[email protected]23e482282013-06-14 16:08:023715TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083716 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3717}
3718
[email protected]23e482282013-06-14 16:08:023719TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083720 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3721}
3722
[email protected]23e482282013-06-14 16:08:023723TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083724 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3725}
3726
[email protected]23e482282013-06-14 16:08:023727TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083728 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3729}
3730
[email protected]23e482282013-06-14 16:08:023731TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083732 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3733}
3734
[email protected]038e9a32008-10-08 22:40:163735// Test the flow when both the proxy server AND origin server require
3736// authentication. Again, this uses basic auth for both since that is
3737// the simplest to mock.
[email protected]23e482282013-06-14 16:08:023738TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:273739 HttpRequestInfo request;
3740 request.method = "GET";
3741 request.url = GURL("http://www.google.com/");
3742 request.load_flags = 0;
3743
[email protected]bb88e1d32013-05-03 23:11:073744 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:013745
[email protected]038e9a32008-10-08 22:40:163746 // Configure against proxy server "myproxy:70".
[email protected]262eec82013-03-19 21:01:363747 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:073748 CreateSession(&session_deps_)));
[email protected]038e9a32008-10-08 22:40:163749
[email protected]f9ee6b52008-11-08 06:46:233750 MockWrite data_writes1[] = {
3751 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3752 "Host: www.google.com\r\n"
3753 "Proxy-Connection: keep-alive\r\n\r\n"),
3754 };
3755
[email protected]038e9a32008-10-08 22:40:163756 MockRead data_reads1[] = {
3757 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3758 // Give a couple authenticate options (only the middle one is actually
3759 // supported).
[email protected]22927ad2009-09-21 19:56:193760 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:163761 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3762 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3763 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3764 // Large content-length -- won't matter, as connection will be reset.
3765 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063766 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:163767 };
3768
3769 // After calling trans->RestartWithAuth() the first time, this is the
3770 // request we should be issuing -- the final header line contains the
3771 // proxy's credentials.
3772 MockWrite data_writes2[] = {
3773 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3774 "Host: www.google.com\r\n"
3775 "Proxy-Connection: keep-alive\r\n"
3776 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3777 };
3778
3779 // Now the proxy server lets the request pass through to origin server.
3780 // The origin server responds with a 401.
3781 MockRead data_reads2[] = {
3782 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3783 // Note: We are using the same realm-name as the proxy server. This is
3784 // completely valid, as realms are unique across hosts.
3785 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3786 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3787 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063788 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:163789 };
3790
3791 // After calling trans->RestartWithAuth() the second time, we should send
3792 // the credentials for both the proxy and origin server.
3793 MockWrite data_writes3[] = {
3794 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3795 "Host: www.google.com\r\n"
3796 "Proxy-Connection: keep-alive\r\n"
3797 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3798 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3799 };
3800
3801 // Lastly we get the desired content.
3802 MockRead data_reads3[] = {
3803 MockRead("HTTP/1.0 200 OK\r\n"),
3804 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3805 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063806 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:163807 };
3808
[email protected]31a2bfe2010-02-09 08:03:393809 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3810 data_writes1, arraysize(data_writes1));
3811 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3812 data_writes2, arraysize(data_writes2));
3813 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3814 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:073815 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3816 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3817 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:163818
[email protected]49639fa2011-12-20 23:22:413819 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:163820
[email protected]49639fa2011-12-20 23:22:413821 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423822 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163823
3824 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423825 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163826
[email protected]1c773ea12009-04-28 19:58:423827 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503828 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043829 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163830
[email protected]49639fa2011-12-20 23:22:413831 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:163832
[email protected]49639fa2011-12-20 23:22:413833 rv = trans->RestartWithAuth(
3834 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423835 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163836
3837 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423838 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163839
3840 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503841 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043842 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163843
[email protected]49639fa2011-12-20 23:22:413844 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:163845
[email protected]49639fa2011-12-20 23:22:413846 rv = trans->RestartWithAuth(
3847 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423848 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163849
3850 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423851 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163852
3853 response = trans->GetResponseInfo();
3854 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3855 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:163856}
[email protected]4ddaf2502008-10-23 18:26:193857
[email protected]ea9dc9a2009-09-05 00:43:323858// For the NTLM implementation using SSPI, we skip the NTLM tests since we
3859// can't hook into its internals to cause it to generate predictable NTLM
3860// authorization headers.
3861#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:293862// The NTLM authentication unit tests were generated by capturing the HTTP
3863// requests and responses using Fiddler 2 and inspecting the generated random
3864// bytes in the debugger.
3865
3866// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:023867TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:423868 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:243869 request.method = "GET";
3870 request.url = GURL("http://172.22.68.17/kids/login.aspx");
3871 request.load_flags = 0;
3872
[email protected]cb9bf6ca2011-01-28 13:15:273873 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
3874 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:073875 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273876
[email protected]3f918782009-02-28 01:29:243877 MockWrite data_writes1[] = {
3878 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3879 "Host: 172.22.68.17\r\n"
3880 "Connection: keep-alive\r\n\r\n"),
3881 };
3882
3883 MockRead data_reads1[] = {
3884 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043885 // Negotiate and NTLM are often requested together. However, we only want
3886 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3887 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:243888 MockRead("WWW-Authenticate: NTLM\r\n"),
3889 MockRead("Connection: close\r\n"),
3890 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363891 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243892 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:063893 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:243894 };
3895
3896 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:223897 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:243898 // request we should be issuing -- the final header line contains a Type
3899 // 1 message.
3900 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3901 "Host: 172.22.68.17\r\n"
3902 "Connection: keep-alive\r\n"
3903 "Authorization: NTLM "
3904 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3905
3906 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3907 // (the credentials for the origin server). The second request continues
3908 // on the same connection.
3909 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3910 "Host: 172.22.68.17\r\n"
3911 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:293912 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3913 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3914 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
3915 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
3916 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243917 };
3918
3919 MockRead data_reads2[] = {
3920 // The origin server responds with a Type 2 message.
3921 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3922 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:293923 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:243924 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3925 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3926 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3927 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3928 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3929 "BtAAAAAAA=\r\n"),
3930 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363931 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243932 MockRead("You are not authorized to view this page\r\n"),
3933
3934 // Lastly we get the desired content.
3935 MockRead("HTTP/1.1 200 OK\r\n"),
3936 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3937 MockRead("Content-Length: 13\r\n\r\n"),
3938 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:063939 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:243940 };
3941
[email protected]31a2bfe2010-02-09 08:03:393942 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3943 data_writes1, arraysize(data_writes1));
3944 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3945 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3947 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:243948
[email protected]49639fa2011-12-20 23:22:413949 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:243950
[email protected]262eec82013-03-19 21:01:363951 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503952 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503953
[email protected]49639fa2011-12-20 23:22:413954 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423955 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243956
3957 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423958 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243959
[email protected]0757e7702009-03-27 04:00:223960 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3961
[email protected]1c773ea12009-04-28 19:58:423962 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043963 ASSERT_FALSE(response == NULL);
3964 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:243965
[email protected]49639fa2011-12-20 23:22:413966 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:253967
[email protected]f3cf9802011-10-28 18:44:583968 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:413969 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:253970 EXPECT_EQ(ERR_IO_PENDING, rv);
3971
3972 rv = callback2.WaitForResult();
3973 EXPECT_EQ(OK, rv);
3974
3975 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3976
3977 response = trans->GetResponseInfo();
3978 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:253979 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3980
[email protected]49639fa2011-12-20 23:22:413981 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:243982
[email protected]49639fa2011-12-20 23:22:413983 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423984 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243985
[email protected]0757e7702009-03-27 04:00:223986 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423987 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243988
3989 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503990 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:243991 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3992 EXPECT_EQ(13, response->headers->GetContentLength());
3993}
3994
[email protected]385a4672009-03-11 22:21:293995// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:023996TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:423997 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:293998 request.method = "GET";
3999 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4000 request.load_flags = 0;
4001
[email protected]cb9bf6ca2011-01-28 13:15:274002 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4003 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074004 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274005
[email protected]385a4672009-03-11 22:21:294006 MockWrite data_writes1[] = {
4007 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4008 "Host: 172.22.68.17\r\n"
4009 "Connection: keep-alive\r\n\r\n"),
4010 };
4011
4012 MockRead data_reads1[] = {
4013 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044014 // Negotiate and NTLM are often requested together. However, we only want
4015 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4016 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294017 MockRead("WWW-Authenticate: NTLM\r\n"),
4018 MockRead("Connection: close\r\n"),
4019 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364020 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294021 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064022 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294023 };
4024
4025 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224026 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294027 // request we should be issuing -- the final header line contains a Type
4028 // 1 message.
4029 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4030 "Host: 172.22.68.17\r\n"
4031 "Connection: keep-alive\r\n"
4032 "Authorization: NTLM "
4033 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4034
4035 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4036 // (the credentials for the origin server). The second request continues
4037 // on the same connection.
4038 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4039 "Host: 172.22.68.17\r\n"
4040 "Connection: keep-alive\r\n"
4041 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4042 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4043 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4044 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4045 "4Ww7b7E=\r\n\r\n"),
4046 };
4047
4048 MockRead data_reads2[] = {
4049 // The origin server responds with a Type 2 message.
4050 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4051 MockRead("WWW-Authenticate: NTLM "
4052 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4053 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4054 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4055 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4056 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4057 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4058 "BtAAAAAAA=\r\n"),
4059 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364060 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294061 MockRead("You are not authorized to view this page\r\n"),
4062
4063 // Wrong password.
4064 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294065 MockRead("WWW-Authenticate: NTLM\r\n"),
4066 MockRead("Connection: close\r\n"),
4067 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364068 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294069 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064070 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294071 };
4072
4073 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224074 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294075 // request we should be issuing -- the final header line contains a Type
4076 // 1 message.
4077 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4078 "Host: 172.22.68.17\r\n"
4079 "Connection: keep-alive\r\n"
4080 "Authorization: NTLM "
4081 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4082
4083 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4084 // (the credentials for the origin server). The second request continues
4085 // on the same connection.
4086 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4087 "Host: 172.22.68.17\r\n"
4088 "Connection: keep-alive\r\n"
4089 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4090 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4091 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4092 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4093 "+4MUm7c=\r\n\r\n"),
4094 };
4095
4096 MockRead data_reads3[] = {
4097 // The origin server responds with a Type 2 message.
4098 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4099 MockRead("WWW-Authenticate: NTLM "
4100 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4101 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4102 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4103 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4104 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4105 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4106 "BtAAAAAAA=\r\n"),
4107 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364108 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294109 MockRead("You are not authorized to view this page\r\n"),
4110
4111 // Lastly we get the desired content.
4112 MockRead("HTTP/1.1 200 OK\r\n"),
4113 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4114 MockRead("Content-Length: 13\r\n\r\n"),
4115 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064116 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294117 };
4118
[email protected]31a2bfe2010-02-09 08:03:394119 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4120 data_writes1, arraysize(data_writes1));
4121 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4122 data_writes2, arraysize(data_writes2));
4123 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4124 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074125 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4126 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4127 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294128
[email protected]49639fa2011-12-20 23:22:414129 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294130
[email protected]262eec82013-03-19 21:01:364131 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504133
[email protected]49639fa2011-12-20 23:22:414134 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424135 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294136
4137 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424138 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294139
[email protected]0757e7702009-03-27 04:00:224140 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294141
[email protected]1c773ea12009-04-28 19:58:424142 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504143 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044144 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294145
[email protected]49639fa2011-12-20 23:22:414146 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294147
[email protected]0757e7702009-03-27 04:00:224148 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584149 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414150 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424151 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294152
[email protected]10af5fe72011-01-31 16:17:254153 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424154 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294155
[email protected]0757e7702009-03-27 04:00:224156 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414157 TestCompletionCallback callback3;
4158 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424159 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254160 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424161 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224162 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4163
4164 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044165 ASSERT_FALSE(response == NULL);
4166 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224167
[email protected]49639fa2011-12-20 23:22:414168 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224169
4170 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584171 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414172 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254173 EXPECT_EQ(ERR_IO_PENDING, rv);
4174
4175 rv = callback4.WaitForResult();
4176 EXPECT_EQ(OK, rv);
4177
4178 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4179
[email protected]49639fa2011-12-20 23:22:414180 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254181
4182 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414183 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424184 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224185
4186 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424187 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224188
[email protected]385a4672009-03-11 22:21:294189 response = trans->GetResponseInfo();
4190 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4191 EXPECT_EQ(13, response->headers->GetContentLength());
4192}
[email protected]ea9dc9a2009-09-05 00:43:324193#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294194
[email protected]4ddaf2502008-10-23 18:26:194195// Test reading a server response which has only headers, and no body.
4196// After some maximum number of bytes is consumed, the transaction should
4197// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024198TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424199 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194200 request.method = "GET";
4201 request.url = GURL("http://www.google.com/");
4202 request.load_flags = 0;
4203
[email protected]cb9bf6ca2011-01-28 13:15:274204 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364205 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074206 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274207
[email protected]b75b7b2f2009-10-06 00:54:534208 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434209 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534210 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194211
4212 MockRead data_reads[] = {
4213 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064214 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194215 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064216 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194217 };
[email protected]31a2bfe2010-02-09 08:03:394218 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074219 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194220
[email protected]49639fa2011-12-20 23:22:414221 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194222
[email protected]49639fa2011-12-20 23:22:414223 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424224 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194225
4226 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424227 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194228
[email protected]1c773ea12009-04-28 19:58:424229 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194230 EXPECT_TRUE(response == NULL);
4231}
[email protected]f4e426b2008-11-05 00:24:494232
4233// Make sure that we don't try to reuse a TCPClientSocket when failing to
4234// establish tunnel.
4235// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024236TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234237 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274238 HttpRequestInfo request;
4239 request.method = "GET";
4240 request.url = GURL("https://www.google.com/");
4241 request.load_flags = 0;
4242
[email protected]f4e426b2008-11-05 00:24:494243 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074244 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014245
[email protected]bb88e1d32013-05-03 23:11:074246 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494247
[email protected]262eec82013-03-19 21:01:364248 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494250
[email protected]f4e426b2008-11-05 00:24:494251 // Since we have proxy, should try to establish tunnel.
4252 MockWrite data_writes1[] = {
4253 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454254 "Host: www.google.com\r\n"
4255 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494256 };
4257
[email protected]77848d12008-11-14 00:00:224258 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494259 // connection. Usually a proxy would return 501 (not implemented),
4260 // or 200 (tunnel established).
4261 MockRead data_reads1[] = {
4262 MockRead("HTTP/1.1 404 Not Found\r\n"),
4263 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064264 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494265 };
4266
[email protected]31a2bfe2010-02-09 08:03:394267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4268 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494270
[email protected]49639fa2011-12-20 23:22:414271 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494272
[email protected]49639fa2011-12-20 23:22:414273 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424274 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494275
4276 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424277 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494278
[email protected]1c773ea12009-04-28 19:58:424279 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084280 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494281
[email protected]b4404c02009-04-10 16:38:524282 // Empty the current queue. This is necessary because idle sockets are
4283 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344284 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524285
[email protected]f4e426b2008-11-05 00:24:494286 // We now check to make sure the TCPClientSocket was not added back to
4287 // the pool.
[email protected]90499482013-06-01 00:39:504288 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494289 trans.reset();
[email protected]2da659e2013-05-23 20:51:344290 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494291 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504292 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494293}
[email protected]372d34a2008-11-05 21:30:514294
[email protected]1b157c02009-04-21 01:55:404295// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024296TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424297 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404298 request.method = "GET";
4299 request.url = GURL("http://www.google.com/");
4300 request.load_flags = 0;
4301
[email protected]bb88e1d32013-05-03 23:11:074302 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274303
[email protected]262eec82013-03-19 21:01:364304 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274306
[email protected]1b157c02009-04-21 01:55:404307 MockRead data_reads[] = {
4308 // A part of the response body is received with the response headers.
4309 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4310 // The rest of the response body is received in two parts.
4311 MockRead("lo"),
4312 MockRead(" world"),
4313 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064314 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404315 };
4316
[email protected]31a2bfe2010-02-09 08:03:394317 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074318 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404319
[email protected]49639fa2011-12-20 23:22:414320 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404321
[email protected]49639fa2011-12-20 23:22:414322 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424323 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404324
4325 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424326 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404327
[email protected]1c773ea12009-04-28 19:58:424328 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504329 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404330
[email protected]90499482013-06-01 00:39:504331 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404332 std::string status_line = response->headers->GetStatusLine();
4333 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4334
[email protected]90499482013-06-01 00:39:504335 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404336
4337 std::string response_data;
4338 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424339 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404340 EXPECT_EQ("hello world", response_data);
4341
4342 // Empty the current queue. This is necessary because idle sockets are
4343 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344344 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404345
4346 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504347 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404348}
4349
[email protected]76a505b2010-08-25 06:23:004350// Make sure that we recycle a SSL socket after reading all of the response
4351// body.
[email protected]23e482282013-06-14 16:08:024352TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004353 HttpRequestInfo request;
4354 request.method = "GET";
4355 request.url = GURL("https://www.google.com/");
4356 request.load_flags = 0;
4357
4358 MockWrite data_writes[] = {
4359 MockWrite("GET / HTTP/1.1\r\n"
4360 "Host: www.google.com\r\n"
4361 "Connection: keep-alive\r\n\r\n"),
4362 };
4363
4364 MockRead data_reads[] = {
4365 MockRead("HTTP/1.1 200 OK\r\n"),
4366 MockRead("Content-Length: 11\r\n\r\n"),
4367 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064368 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004369 };
4370
[email protected]8ddf8322012-02-23 18:08:064371 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004373
4374 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4375 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074376 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004377
[email protected]49639fa2011-12-20 23:22:414378 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004379
[email protected]bb88e1d32013-05-03 23:11:074380 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364381 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504382 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004383
[email protected]49639fa2011-12-20 23:22:414384 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004385
4386 EXPECT_EQ(ERR_IO_PENDING, rv);
4387 EXPECT_EQ(OK, callback.WaitForResult());
4388
4389 const HttpResponseInfo* response = trans->GetResponseInfo();
4390 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504391 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004392 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4393
[email protected]90499482013-06-01 00:39:504394 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004395
4396 std::string response_data;
4397 rv = ReadTransaction(trans.get(), &response_data);
4398 EXPECT_EQ(OK, rv);
4399 EXPECT_EQ("hello world", response_data);
4400
4401 // Empty the current queue. This is necessary because idle sockets are
4402 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344403 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004404
4405 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504406 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004407}
4408
4409// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4410// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024411TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004412 HttpRequestInfo request;
4413 request.method = "GET";
4414 request.url = GURL("https://www.google.com/");
4415 request.load_flags = 0;
4416
4417 MockWrite data_writes[] = {
4418 MockWrite("GET / HTTP/1.1\r\n"
4419 "Host: www.google.com\r\n"
4420 "Connection: keep-alive\r\n\r\n"),
4421 MockWrite("GET / HTTP/1.1\r\n"
4422 "Host: www.google.com\r\n"
4423 "Connection: keep-alive\r\n\r\n"),
4424 };
4425
4426 MockRead data_reads[] = {
4427 MockRead("HTTP/1.1 200 OK\r\n"),
4428 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064429 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004430 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064431 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004432 };
4433
[email protected]8ddf8322012-02-23 18:08:064434 SSLSocketDataProvider ssl(ASYNC, OK);
4435 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004438
4439 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4440 data_writes, arraysize(data_writes));
4441 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4442 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074443 session_deps_.socket_factory->AddSocketDataProvider(&data);
4444 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004445
[email protected]49639fa2011-12-20 23:22:414446 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004447
[email protected]bb88e1d32013-05-03 23:11:074448 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364449 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504450 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004451
[email protected]49639fa2011-12-20 23:22:414452 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004453
4454 EXPECT_EQ(ERR_IO_PENDING, rv);
4455 EXPECT_EQ(OK, callback.WaitForResult());
4456
4457 const HttpResponseInfo* response = trans->GetResponseInfo();
4458 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504459 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004460 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4461
[email protected]90499482013-06-01 00:39:504462 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004463
4464 std::string response_data;
4465 rv = ReadTransaction(trans.get(), &response_data);
4466 EXPECT_EQ(OK, rv);
4467 EXPECT_EQ("hello world", response_data);
4468
4469 // Empty the current queue. This is necessary because idle sockets are
4470 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344471 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004472
4473 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504474 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004475
4476 // Now start the second transaction, which should reuse the previous socket.
4477
[email protected]90499482013-06-01 00:39:504478 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004479
[email protected]49639fa2011-12-20 23:22:414480 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004481
4482 EXPECT_EQ(ERR_IO_PENDING, rv);
4483 EXPECT_EQ(OK, callback.WaitForResult());
4484
4485 response = trans->GetResponseInfo();
4486 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504487 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004488 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4489
[email protected]90499482013-06-01 00:39:504490 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004491
4492 rv = ReadTransaction(trans.get(), &response_data);
4493 EXPECT_EQ(OK, rv);
4494 EXPECT_EQ("hello world", response_data);
4495
4496 // Empty the current queue. This is necessary because idle sockets are
4497 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344498 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004499
4500 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504501 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004502}
4503
[email protected]b4404c02009-04-10 16:38:524504// Make sure that we recycle a socket after a zero-length response.
4505// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024506TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424507 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524508 request.method = "GET";
4509 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4510 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4511 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4512 "rt=prt.2642,ol.2649,xjs.2951");
4513 request.load_flags = 0;
4514
[email protected]bb88e1d32013-05-03 23:11:074515 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274516
[email protected]262eec82013-03-19 21:01:364517 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504518 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274519
[email protected]b4404c02009-04-10 16:38:524520 MockRead data_reads[] = {
4521 MockRead("HTTP/1.1 204 No Content\r\n"
4522 "Content-Length: 0\r\n"
4523 "Content-Type: text/html\r\n\r\n"),
4524 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064525 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524526 };
4527
[email protected]31a2bfe2010-02-09 08:03:394528 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074529 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524530
[email protected]49639fa2011-12-20 23:22:414531 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524532
[email protected]49639fa2011-12-20 23:22:414533 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424534 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524535
4536 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424537 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524538
[email protected]1c773ea12009-04-28 19:58:424539 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504540 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524541
[email protected]90499482013-06-01 00:39:504542 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524543 std::string status_line = response->headers->GetStatusLine();
4544 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4545
[email protected]90499482013-06-01 00:39:504546 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524547
4548 std::string response_data;
4549 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424550 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524551 EXPECT_EQ("", response_data);
4552
4553 // Empty the current queue. This is necessary because idle sockets are
4554 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344555 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524556
4557 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504558 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524559}
4560
[email protected]23e482282013-06-14 16:08:024561TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064562 ScopedVector<UploadElementReader> element_readers;
4563 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204564 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274565
[email protected]1c773ea12009-04-28 19:58:424566 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514567 // Transaction 1: a GET request that succeeds. The socket is recycled
4568 // after use.
4569 request[0].method = "GET";
4570 request[0].url = GURL("http://www.google.com/");
4571 request[0].load_flags = 0;
4572 // Transaction 2: a POST request. Reuses the socket kept alive from
4573 // transaction 1. The first attempts fails when writing the POST data.
4574 // This causes the transaction to retry with a new socket. The second
4575 // attempt succeeds.
4576 request[1].method = "POST";
4577 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274578 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514579 request[1].load_flags = 0;
4580
[email protected]bb88e1d32013-05-03 23:11:074581 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514582
4583 // The first socket is used for transaction 1 and the first attempt of
4584 // transaction 2.
4585
4586 // The response of transaction 1.
4587 MockRead data_reads1[] = {
4588 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4589 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064590 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514591 };
4592 // The mock write results of transaction 1 and the first attempt of
4593 // transaction 2.
4594 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064595 MockWrite(SYNCHRONOUS, 64), // GET
4596 MockWrite(SYNCHRONOUS, 93), // POST
4597 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514598 };
[email protected]31a2bfe2010-02-09 08:03:394599 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4600 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514601
4602 // The second socket is used for the second attempt of transaction 2.
4603
4604 // The response of transaction 2.
4605 MockRead data_reads2[] = {
4606 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4607 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064608 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514609 };
4610 // The mock write results of the second attempt of transaction 2.
4611 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064612 MockWrite(SYNCHRONOUS, 93), // POST
4613 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514614 };
[email protected]31a2bfe2010-02-09 08:03:394615 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4616 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514617
[email protected]bb88e1d32013-05-03 23:11:074618 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4619 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514620
4621 const char* kExpectedResponseData[] = {
4622 "hello world", "welcome"
4623 };
4624
4625 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424626 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514628
[email protected]49639fa2011-12-20 23:22:414629 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514630
[email protected]49639fa2011-12-20 23:22:414631 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424632 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514633
4634 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424635 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514636
[email protected]1c773ea12009-04-28 19:58:424637 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504638 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514639
[email protected]90499482013-06-01 00:39:504640 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514641 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4642
4643 std::string response_data;
4644 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424645 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514646 EXPECT_EQ(kExpectedResponseData[i], response_data);
4647 }
4648}
[email protected]f9ee6b52008-11-08 06:46:234649
4650// Test the request-challenge-retry sequence for basic auth when there is
4651// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164652// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024653TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424654 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234655 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294656 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414657 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294658
[email protected]cb9bf6ca2011-01-28 13:15:274659 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364660 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074661 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274662
[email protected]a97cca42009-08-14 01:00:294663 // The password contains an escaped character -- for this test to pass it
4664 // will need to be unescaped by HttpNetworkTransaction.
4665 EXPECT_EQ("b%40r", request.url.password());
4666
[email protected]f9ee6b52008-11-08 06:46:234667 MockWrite data_writes1[] = {
4668 MockWrite("GET / HTTP/1.1\r\n"
4669 "Host: www.google.com\r\n"
4670 "Connection: keep-alive\r\n\r\n"),
4671 };
4672
4673 MockRead data_reads1[] = {
4674 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4675 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4676 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064677 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234678 };
4679
[email protected]2262e3a2012-05-22 16:08:164680 // After the challenge above, the transaction will be restarted using the
4681 // identity from the url (foo, b@r) to answer the challenge.
4682 MockWrite data_writes2[] = {
4683 MockWrite("GET / HTTP/1.1\r\n"
4684 "Host: www.google.com\r\n"
4685 "Connection: keep-alive\r\n"
4686 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4687 };
4688
4689 MockRead data_reads2[] = {
4690 MockRead("HTTP/1.0 200 OK\r\n"),
4691 MockRead("Content-Length: 100\r\n\r\n"),
4692 MockRead(SYNCHRONOUS, OK),
4693 };
4694
[email protected]31a2bfe2010-02-09 08:03:394695 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4696 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164697 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4698 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074699 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4700 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234701
[email protected]49639fa2011-12-20 23:22:414702 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414703 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424704 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234705 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424706 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164707 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4708
4709 TestCompletionCallback callback2;
4710 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4711 EXPECT_EQ(ERR_IO_PENDING, rv);
4712 rv = callback2.WaitForResult();
4713 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224714 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4715
[email protected]2262e3a2012-05-22 16:08:164716 const HttpResponseInfo* response = trans->GetResponseInfo();
4717 ASSERT_TRUE(response != NULL);
4718
4719 // There is no challenge info, since the identity in URL worked.
4720 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4721
4722 EXPECT_EQ(100, response->headers->GetContentLength());
4723
4724 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344725 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164726}
4727
4728// Test the request-challenge-retry sequence for basic auth when there is an
4729// incorrect identity in the URL. The identity from the URL should be used only
4730// once.
[email protected]23e482282013-06-14 16:08:024731TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164732 HttpRequestInfo request;
4733 request.method = "GET";
4734 // Note: the URL has a username:password in it. The password "baz" is
4735 // wrong (should be "bar").
4736 request.url = GURL("http://foo:[email protected]/");
4737
4738 request.load_flags = LOAD_NORMAL;
4739
[email protected]2262e3a2012-05-22 16:08:164740 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364741 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074742 CreateSession(&session_deps_)));
[email protected]2262e3a2012-05-22 16:08:164743
4744 MockWrite data_writes1[] = {
4745 MockWrite("GET / HTTP/1.1\r\n"
4746 "Host: www.google.com\r\n"
4747 "Connection: keep-alive\r\n\r\n"),
4748 };
4749
4750 MockRead data_reads1[] = {
4751 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4752 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4753 MockRead("Content-Length: 10\r\n\r\n"),
4754 MockRead(SYNCHRONOUS, ERR_FAILED),
4755 };
4756
4757 // After the challenge above, the transaction will be restarted using the
4758 // identity from the url (foo, baz) to answer the challenge.
4759 MockWrite data_writes2[] = {
4760 MockWrite("GET / HTTP/1.1\r\n"
4761 "Host: www.google.com\r\n"
4762 "Connection: keep-alive\r\n"
4763 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4764 };
4765
4766 MockRead data_reads2[] = {
4767 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4768 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4769 MockRead("Content-Length: 10\r\n\r\n"),
4770 MockRead(SYNCHRONOUS, ERR_FAILED),
4771 };
4772
4773 // After the challenge above, the transaction will be restarted using the
4774 // identity supplied by the user (foo, bar) to answer the challenge.
4775 MockWrite data_writes3[] = {
4776 MockWrite("GET / HTTP/1.1\r\n"
4777 "Host: www.google.com\r\n"
4778 "Connection: keep-alive\r\n"
4779 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4780 };
4781
4782 MockRead data_reads3[] = {
4783 MockRead("HTTP/1.0 200 OK\r\n"),
4784 MockRead("Content-Length: 100\r\n\r\n"),
4785 MockRead(SYNCHRONOUS, OK),
4786 };
4787
4788 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4789 data_writes1, arraysize(data_writes1));
4790 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4791 data_writes2, arraysize(data_writes2));
4792 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4793 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074794 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4795 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4796 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:164797
4798 TestCompletionCallback callback1;
4799
4800 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4801 EXPECT_EQ(ERR_IO_PENDING, rv);
4802
4803 rv = callback1.WaitForResult();
4804 EXPECT_EQ(OK, rv);
4805
4806 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4807 TestCompletionCallback callback2;
4808 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4809 EXPECT_EQ(ERR_IO_PENDING, rv);
4810 rv = callback2.WaitForResult();
4811 EXPECT_EQ(OK, rv);
4812 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4813
4814 const HttpResponseInfo* response = trans->GetResponseInfo();
4815 ASSERT_TRUE(response != NULL);
4816 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4817
4818 TestCompletionCallback callback3;
4819 rv = trans->RestartWithAuth(
4820 AuthCredentials(kFoo, kBar), callback3.callback());
4821 EXPECT_EQ(ERR_IO_PENDING, rv);
4822 rv = callback3.WaitForResult();
4823 EXPECT_EQ(OK, rv);
4824 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4825
4826 response = trans->GetResponseInfo();
4827 ASSERT_TRUE(response != NULL);
4828
4829 // There is no challenge info, since the identity worked.
4830 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4831
4832 EXPECT_EQ(100, response->headers->GetContentLength());
4833
[email protected]ea9dc9a2009-09-05 00:43:324834 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344835 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:324836}
4837
[email protected]f9ee6b52008-11-08 06:46:234838// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:024839TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:074840 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:234841
4842 // Transaction 1: authenticate (foo, bar) on MyRealm1
4843 {
[email protected]1c773ea12009-04-28 19:58:424844 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234845 request.method = "GET";
4846 request.url = GURL("http://www.google.com/x/y/z");
4847 request.load_flags = 0;
4848
[email protected]262eec82013-03-19 21:01:364849 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274851
[email protected]f9ee6b52008-11-08 06:46:234852 MockWrite data_writes1[] = {
4853 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4854 "Host: www.google.com\r\n"
4855 "Connection: keep-alive\r\n\r\n"),
4856 };
4857
4858 MockRead data_reads1[] = {
4859 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4860 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4861 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064862 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234863 };
4864
4865 // Resend with authorization (username=foo, password=bar)
4866 MockWrite data_writes2[] = {
4867 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4868 "Host: www.google.com\r\n"
4869 "Connection: keep-alive\r\n"
4870 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4871 };
4872
4873 // Sever accepts the authorization.
4874 MockRead data_reads2[] = {
4875 MockRead("HTTP/1.0 200 OK\r\n"),
4876 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064877 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234878 };
4879
[email protected]31a2bfe2010-02-09 08:03:394880 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4881 data_writes1, arraysize(data_writes1));
4882 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4883 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074884 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4885 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234886
[email protected]49639fa2011-12-20 23:22:414887 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234888
[email protected]49639fa2011-12-20 23:22:414889 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424890 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234891
4892 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424893 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234894
[email protected]1c773ea12009-04-28 19:58:424895 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504896 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044897 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:234898
[email protected]49639fa2011-12-20 23:22:414899 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234900
[email protected]49639fa2011-12-20 23:22:414901 rv = trans->RestartWithAuth(
4902 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424903 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234904
4905 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424906 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234907
4908 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504909 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234910 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4911 EXPECT_EQ(100, response->headers->GetContentLength());
4912 }
4913
4914 // ------------------------------------------------------------------------
4915
4916 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
4917 {
[email protected]1c773ea12009-04-28 19:58:424918 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234919 request.method = "GET";
4920 // Note that Transaction 1 was at /x/y/z, so this is in the same
4921 // protection space as MyRealm1.
4922 request.url = GURL("http://www.google.com/x/y/a/b");
4923 request.load_flags = 0;
4924
[email protected]262eec82013-03-19 21:01:364925 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504926 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274927
[email protected]f9ee6b52008-11-08 06:46:234928 MockWrite data_writes1[] = {
4929 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4930 "Host: www.google.com\r\n"
4931 "Connection: keep-alive\r\n"
4932 // Send preemptive authorization for MyRealm1
4933 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4934 };
4935
4936 // The server didn't like the preemptive authorization, and
4937 // challenges us for a different realm (MyRealm2).
4938 MockRead data_reads1[] = {
4939 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4940 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
4941 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064942 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234943 };
4944
4945 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
4946 MockWrite data_writes2[] = {
4947 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4948 "Host: www.google.com\r\n"
4949 "Connection: keep-alive\r\n"
4950 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4951 };
4952
4953 // Sever accepts the authorization.
4954 MockRead data_reads2[] = {
4955 MockRead("HTTP/1.0 200 OK\r\n"),
4956 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064957 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234958 };
4959
[email protected]31a2bfe2010-02-09 08:03:394960 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4961 data_writes1, arraysize(data_writes1));
4962 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4963 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4965 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234966
[email protected]49639fa2011-12-20 23:22:414967 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234968
[email protected]49639fa2011-12-20 23:22:414969 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424970 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234971
4972 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424973 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234974
[email protected]1c773ea12009-04-28 19:58:424975 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504976 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044977 ASSERT_TRUE(response->auth_challenge.get());
4978 EXPECT_FALSE(response->auth_challenge->is_proxy);
4979 EXPECT_EQ("www.google.com:80",
4980 response->auth_challenge->challenger.ToString());
4981 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
4982 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:234983
[email protected]49639fa2011-12-20 23:22:414984 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234985
[email protected]49639fa2011-12-20 23:22:414986 rv = trans->RestartWithAuth(
4987 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424988 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234989
4990 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424991 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234992
4993 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504994 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234995 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4996 EXPECT_EQ(100, response->headers->GetContentLength());
4997 }
4998
4999 // ------------------------------------------------------------------------
5000
5001 // Transaction 3: Resend a request in MyRealm's protection space --
5002 // succeed with preemptive authorization.
5003 {
[email protected]1c773ea12009-04-28 19:58:425004 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235005 request.method = "GET";
5006 request.url = GURL("http://www.google.com/x/y/z2");
5007 request.load_flags = 0;
5008
[email protected]262eec82013-03-19 21:01:365009 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505010 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275011
[email protected]f9ee6b52008-11-08 06:46:235012 MockWrite data_writes1[] = {
5013 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5014 "Host: www.google.com\r\n"
5015 "Connection: keep-alive\r\n"
5016 // The authorization for MyRealm1 gets sent preemptively
5017 // (since the url is in the same protection space)
5018 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5019 };
5020
5021 // Sever accepts the preemptive authorization
5022 MockRead data_reads1[] = {
5023 MockRead("HTTP/1.0 200 OK\r\n"),
5024 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065025 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235026 };
5027
[email protected]31a2bfe2010-02-09 08:03:395028 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5029 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075030 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235031
[email protected]49639fa2011-12-20 23:22:415032 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235033
[email protected]49639fa2011-12-20 23:22:415034 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425035 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235036
5037 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425038 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235039
[email protected]1c773ea12009-04-28 19:58:425040 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505041 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235042
5043 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5044 EXPECT_EQ(100, response->headers->GetContentLength());
5045 }
5046
5047 // ------------------------------------------------------------------------
5048
5049 // Transaction 4: request another URL in MyRealm (however the
5050 // url is not known to belong to the protection space, so no pre-auth).
5051 {
[email protected]1c773ea12009-04-28 19:58:425052 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235053 request.method = "GET";
5054 request.url = GURL("http://www.google.com/x/1");
5055 request.load_flags = 0;
5056
[email protected]262eec82013-03-19 21:01:365057 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505058 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275059
[email protected]f9ee6b52008-11-08 06:46:235060 MockWrite data_writes1[] = {
5061 MockWrite("GET /x/1 HTTP/1.1\r\n"
5062 "Host: www.google.com\r\n"
5063 "Connection: keep-alive\r\n\r\n"),
5064 };
5065
5066 MockRead data_reads1[] = {
5067 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5068 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5069 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065070 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235071 };
5072
5073 // Resend with authorization from MyRealm's cache.
5074 MockWrite data_writes2[] = {
5075 MockWrite("GET /x/1 HTTP/1.1\r\n"
5076 "Host: www.google.com\r\n"
5077 "Connection: keep-alive\r\n"
5078 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5079 };
5080
5081 // Sever accepts the authorization.
5082 MockRead data_reads2[] = {
5083 MockRead("HTTP/1.0 200 OK\r\n"),
5084 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065085 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235086 };
5087
[email protected]31a2bfe2010-02-09 08:03:395088 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5089 data_writes1, arraysize(data_writes1));
5090 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5091 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075092 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5093 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235094
[email protected]49639fa2011-12-20 23:22:415095 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235096
[email protected]49639fa2011-12-20 23:22:415097 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425098 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235099
5100 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425101 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235102
[email protected]0757e7702009-03-27 04:00:225103 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415104 TestCompletionCallback callback2;
5105 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425106 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225107 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425108 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225109 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5110
[email protected]1c773ea12009-04-28 19:58:425111 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505112 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235113 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5114 EXPECT_EQ(100, response->headers->GetContentLength());
5115 }
5116
5117 // ------------------------------------------------------------------------
5118
5119 // Transaction 5: request a URL in MyRealm, but the server rejects the
5120 // cached identity. Should invalidate and re-prompt.
5121 {
[email protected]1c773ea12009-04-28 19:58:425122 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235123 request.method = "GET";
5124 request.url = GURL("http://www.google.com/p/q/t");
5125 request.load_flags = 0;
5126
[email protected]262eec82013-03-19 21:01:365127 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275129
[email protected]f9ee6b52008-11-08 06:46:235130 MockWrite data_writes1[] = {
5131 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5132 "Host: www.google.com\r\n"
5133 "Connection: keep-alive\r\n\r\n"),
5134 };
5135
5136 MockRead data_reads1[] = {
5137 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5139 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065140 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235141 };
5142
5143 // Resend with authorization from cache for MyRealm.
5144 MockWrite data_writes2[] = {
5145 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5146 "Host: www.google.com\r\n"
5147 "Connection: keep-alive\r\n"
5148 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5149 };
5150
5151 // Sever rejects the authorization.
5152 MockRead data_reads2[] = {
5153 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5154 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5155 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065156 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235157 };
5158
5159 // At this point we should prompt for new credentials for MyRealm.
5160 // Restart with username=foo3, password=foo4.
5161 MockWrite data_writes3[] = {
5162 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5163 "Host: www.google.com\r\n"
5164 "Connection: keep-alive\r\n"
5165 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5166 };
5167
5168 // Sever accepts the authorization.
5169 MockRead data_reads3[] = {
5170 MockRead("HTTP/1.0 200 OK\r\n"),
5171 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065172 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235173 };
5174
[email protected]31a2bfe2010-02-09 08:03:395175 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5176 data_writes1, arraysize(data_writes1));
5177 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5178 data_writes2, arraysize(data_writes2));
5179 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5180 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075181 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5182 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5183 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235184
[email protected]49639fa2011-12-20 23:22:415185 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235186
[email protected]49639fa2011-12-20 23:22:415187 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425188 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235189
5190 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425191 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235192
[email protected]0757e7702009-03-27 04:00:225193 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415194 TestCompletionCallback callback2;
5195 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425196 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225197 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425198 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225199 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5200
[email protected]1c773ea12009-04-28 19:58:425201 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505202 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045203 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235204
[email protected]49639fa2011-12-20 23:22:415205 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235206
[email protected]49639fa2011-12-20 23:22:415207 rv = trans->RestartWithAuth(
5208 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425209 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235210
[email protected]0757e7702009-03-27 04:00:225211 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425212 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235213
5214 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505215 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235216 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5217 EXPECT_EQ(100, response->headers->GetContentLength());
5218 }
5219}
[email protected]89ceba9a2009-03-21 03:46:065220
[email protected]3c32c5f2010-05-18 15:18:125221// Tests that nonce count increments when multiple auth attempts
5222// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025223TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445224 HttpAuthHandlerDigest::Factory* digest_factory =
5225 new HttpAuthHandlerDigest::Factory();
5226 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5227 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5228 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075229 session_deps_.http_auth_handler_factory.reset(digest_factory);
5230 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125231
5232 // Transaction 1: authenticate (foo, bar) on MyRealm1
5233 {
[email protected]3c32c5f2010-05-18 15:18:125234 HttpRequestInfo request;
5235 request.method = "GET";
5236 request.url = GURL("http://www.google.com/x/y/z");
5237 request.load_flags = 0;
5238
[email protected]262eec82013-03-19 21:01:365239 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275241
[email protected]3c32c5f2010-05-18 15:18:125242 MockWrite data_writes1[] = {
5243 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5244 "Host: www.google.com\r\n"
5245 "Connection: keep-alive\r\n\r\n"),
5246 };
5247
5248 MockRead data_reads1[] = {
5249 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5250 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5251 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065252 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125253 };
5254
5255 // Resend with authorization (username=foo, password=bar)
5256 MockWrite data_writes2[] = {
5257 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5258 "Host: www.google.com\r\n"
5259 "Connection: keep-alive\r\n"
5260 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5261 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5262 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5263 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5264 };
5265
5266 // Sever accepts the authorization.
5267 MockRead data_reads2[] = {
5268 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065269 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125270 };
5271
5272 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5273 data_writes1, arraysize(data_writes1));
5274 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5275 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075276 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5277 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125278
[email protected]49639fa2011-12-20 23:22:415279 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125280
[email protected]49639fa2011-12-20 23:22:415281 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125282 EXPECT_EQ(ERR_IO_PENDING, rv);
5283
5284 rv = callback1.WaitForResult();
5285 EXPECT_EQ(OK, rv);
5286
5287 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505288 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045289 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125290
[email protected]49639fa2011-12-20 23:22:415291 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125292
[email protected]49639fa2011-12-20 23:22:415293 rv = trans->RestartWithAuth(
5294 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125295 EXPECT_EQ(ERR_IO_PENDING, rv);
5296
5297 rv = callback2.WaitForResult();
5298 EXPECT_EQ(OK, rv);
5299
5300 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505301 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125302 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5303 }
5304
5305 // ------------------------------------------------------------------------
5306
5307 // Transaction 2: Request another resource in digestive's protection space.
5308 // This will preemptively add an Authorization header which should have an
5309 // "nc" value of 2 (as compared to 1 in the first use.
5310 {
[email protected]3c32c5f2010-05-18 15:18:125311 HttpRequestInfo request;
5312 request.method = "GET";
5313 // Note that Transaction 1 was at /x/y/z, so this is in the same
5314 // protection space as digest.
5315 request.url = GURL("http://www.google.com/x/y/a/b");
5316 request.load_flags = 0;
5317
[email protected]262eec82013-03-19 21:01:365318 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505319 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275320
[email protected]3c32c5f2010-05-18 15:18:125321 MockWrite data_writes1[] = {
5322 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5323 "Host: www.google.com\r\n"
5324 "Connection: keep-alive\r\n"
5325 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5326 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5327 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5328 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5329 };
5330
5331 // Sever accepts the authorization.
5332 MockRead data_reads1[] = {
5333 MockRead("HTTP/1.0 200 OK\r\n"),
5334 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065335 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125336 };
5337
5338 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5339 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075340 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125341
[email protected]49639fa2011-12-20 23:22:415342 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125343
[email protected]49639fa2011-12-20 23:22:415344 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125345 EXPECT_EQ(ERR_IO_PENDING, rv);
5346
5347 rv = callback1.WaitForResult();
5348 EXPECT_EQ(OK, rv);
5349
5350 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505351 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125352 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5353 }
5354}
5355
[email protected]89ceba9a2009-03-21 03:46:065356// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025357TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065358 // Create a transaction (the dependencies aren't important).
[email protected]d207a5f2009-06-04 05:28:405359 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:365360 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075361 CreateSession(&session_deps_)));
[email protected]89ceba9a2009-03-21 03:46:065362
5363 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065364 trans->read_buf_ = new IOBuffer(15);
5365 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205366 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065367
5368 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145369 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575370 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085371 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575372 response->response_time = base::Time::Now();
5373 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065374
5375 { // Setup state for response_.vary_data
5376 HttpRequestInfo request;
5377 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5378 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275379 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435380 request.extra_headers.SetHeader("Foo", "1");
5381 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505382 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065383 }
5384
5385 // Cause the above state to be reset.
5386 trans->ResetStateForRestart();
5387
5388 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075389 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065390 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205391 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575392 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5393 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045394 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085395 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575396 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065397}
5398
[email protected]bacff652009-03-31 17:50:335399// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025400TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335401 HttpRequestInfo request;
5402 request.method = "GET";
5403 request.url = GURL("https://www.google.com/");
5404 request.load_flags = 0;
5405
[email protected]cb9bf6ca2011-01-28 13:15:275406 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365407 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075408 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:275409
[email protected]bacff652009-03-31 17:50:335410 MockWrite data_writes[] = {
5411 MockWrite("GET / HTTP/1.1\r\n"
5412 "Host: www.google.com\r\n"
5413 "Connection: keep-alive\r\n\r\n"),
5414 };
5415
5416 MockRead data_reads[] = {
5417 MockRead("HTTP/1.0 200 OK\r\n"),
5418 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5419 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065420 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335421 };
5422
[email protected]5ecc992a42009-11-11 01:41:595423 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395424 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5425 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065426 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5427 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335428
[email protected]bb88e1d32013-05-03 23:11:075429 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5430 session_deps_.socket_factory->AddSocketDataProvider(&data);
5431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335433
[email protected]49639fa2011-12-20 23:22:415434 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335435
[email protected]49639fa2011-12-20 23:22:415436 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335437 EXPECT_EQ(ERR_IO_PENDING, rv);
5438
5439 rv = callback.WaitForResult();
5440 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5441
[email protected]49639fa2011-12-20 23:22:415442 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335443 EXPECT_EQ(ERR_IO_PENDING, rv);
5444
5445 rv = callback.WaitForResult();
5446 EXPECT_EQ(OK, rv);
5447
5448 const HttpResponseInfo* response = trans->GetResponseInfo();
5449
[email protected]fe2255a2011-09-20 19:37:505450 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335451 EXPECT_EQ(100, response->headers->GetContentLength());
5452}
5453
5454// Test HTTPS connections to a site with a bad certificate, going through a
5455// proxy
[email protected]23e482282013-06-14 16:08:025456TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075457 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335458
5459 HttpRequestInfo request;
5460 request.method = "GET";
5461 request.url = GURL("https://www.google.com/");
5462 request.load_flags = 0;
5463
5464 MockWrite proxy_writes[] = {
5465 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455466 "Host: www.google.com\r\n"
5467 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335468 };
5469
5470 MockRead proxy_reads[] = {
5471 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065472 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335473 };
5474
5475 MockWrite data_writes[] = {
5476 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455477 "Host: www.google.com\r\n"
5478 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335479 MockWrite("GET / HTTP/1.1\r\n"
5480 "Host: www.google.com\r\n"
5481 "Connection: keep-alive\r\n\r\n"),
5482 };
5483
5484 MockRead data_reads[] = {
5485 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5486 MockRead("HTTP/1.0 200 OK\r\n"),
5487 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5488 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065489 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335490 };
5491
[email protected]31a2bfe2010-02-09 08:03:395492 StaticSocketDataProvider ssl_bad_certificate(
5493 proxy_reads, arraysize(proxy_reads),
5494 proxy_writes, arraysize(proxy_writes));
5495 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5496 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065497 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5498 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335499
[email protected]bb88e1d32013-05-03 23:11:075500 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5501 session_deps_.socket_factory->AddSocketDataProvider(&data);
5502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335504
[email protected]49639fa2011-12-20 23:22:415505 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335506
5507 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075508 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335509
[email protected]d207a5f2009-06-04 05:28:405510 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365511 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075512 CreateSession(&session_deps_)));
[email protected]bacff652009-03-31 17:50:335513
[email protected]49639fa2011-12-20 23:22:415514 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335515 EXPECT_EQ(ERR_IO_PENDING, rv);
5516
5517 rv = callback.WaitForResult();
5518 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5519
[email protected]49639fa2011-12-20 23:22:415520 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335521 EXPECT_EQ(ERR_IO_PENDING, rv);
5522
5523 rv = callback.WaitForResult();
5524 EXPECT_EQ(OK, rv);
5525
5526 const HttpResponseInfo* response = trans->GetResponseInfo();
5527
[email protected]fe2255a2011-09-20 19:37:505528 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335529 EXPECT_EQ(100, response->headers->GetContentLength());
5530 }
5531}
5532
[email protected]2df19bb2010-08-25 20:13:465533
5534// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025535TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075536 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205537 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5538 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075539 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465540
5541 HttpRequestInfo request;
5542 request.method = "GET";
5543 request.url = GURL("https://www.google.com/");
5544 request.load_flags = 0;
5545
5546 MockWrite data_writes[] = {
5547 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5548 "Host: www.google.com\r\n"
5549 "Proxy-Connection: keep-alive\r\n\r\n"),
5550 MockWrite("GET / HTTP/1.1\r\n"
5551 "Host: www.google.com\r\n"
5552 "Connection: keep-alive\r\n\r\n"),
5553 };
5554
5555 MockRead data_reads[] = {
5556 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5557 MockRead("HTTP/1.1 200 OK\r\n"),
5558 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5559 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065560 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465561 };
5562
5563 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5564 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065565 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5566 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465567
[email protected]bb88e1d32013-05-03 23:11:075568 session_deps_.socket_factory->AddSocketDataProvider(&data);
5569 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5570 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465571
[email protected]49639fa2011-12-20 23:22:415572 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465573
5574 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365575 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075576 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:465577
[email protected]49639fa2011-12-20 23:22:415578 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465579 EXPECT_EQ(ERR_IO_PENDING, rv);
5580
5581 rv = callback.WaitForResult();
5582 EXPECT_EQ(OK, rv);
5583 const HttpResponseInfo* response = trans->GetResponseInfo();
5584
[email protected]fe2255a2011-09-20 19:37:505585 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465586
5587 EXPECT_TRUE(response->headers->IsKeepAlive());
5588 EXPECT_EQ(200, response->headers->response_code());
5589 EXPECT_EQ(100, response->headers->GetContentLength());
5590 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205591
5592 LoadTimingInfo load_timing_info;
5593 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5594 TestLoadTimingNotReusedWithPac(load_timing_info,
5595 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465596}
5597
[email protected]511f6f52010-12-17 03:58:295598// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025599TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075600 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205601 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5602 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075603 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295604
5605 HttpRequestInfo request;
5606 request.method = "GET";
5607 request.url = GURL("https://www.google.com/");
5608 request.load_flags = 0;
5609
5610 MockWrite data_writes[] = {
5611 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5612 "Host: www.google.com\r\n"
5613 "Proxy-Connection: keep-alive\r\n\r\n"),
5614 };
5615
5616 MockRead data_reads[] = {
5617 MockRead("HTTP/1.1 302 Redirect\r\n"),
5618 MockRead("Location: http://login.example.com/\r\n"),
5619 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065620 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295621 };
5622
5623 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5624 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065625 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295626
[email protected]bb88e1d32013-05-03 23:11:075627 session_deps_.socket_factory->AddSocketDataProvider(&data);
5628 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295629
[email protected]49639fa2011-12-20 23:22:415630 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295631
5632 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365633 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075634 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295635
[email protected]49639fa2011-12-20 23:22:415636 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295637 EXPECT_EQ(ERR_IO_PENDING, rv);
5638
5639 rv = callback.WaitForResult();
5640 EXPECT_EQ(OK, rv);
5641 const HttpResponseInfo* response = trans->GetResponseInfo();
5642
[email protected]fe2255a2011-09-20 19:37:505643 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295644
5645 EXPECT_EQ(302, response->headers->response_code());
5646 std::string url;
5647 EXPECT_TRUE(response->headers->IsRedirect(&url));
5648 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205649
5650 // In the case of redirects from proxies, HttpNetworkTransaction returns
5651 // timing for the proxy connection instead of the connection to the host,
5652 // and no send / receive times.
5653 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5654 LoadTimingInfo load_timing_info;
5655 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5656
5657 EXPECT_FALSE(load_timing_info.socket_reused);
5658 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5659
5660 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5661 EXPECT_LE(load_timing_info.proxy_resolve_start,
5662 load_timing_info.proxy_resolve_end);
5663 EXPECT_LE(load_timing_info.proxy_resolve_end,
5664 load_timing_info.connect_timing.connect_start);
5665 ExpectConnectTimingHasTimes(
5666 load_timing_info.connect_timing,
5667 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5668
5669 EXPECT_TRUE(load_timing_info.send_start.is_null());
5670 EXPECT_TRUE(load_timing_info.send_end.is_null());
5671 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:295672}
5673
5674// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025675TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075676 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295677 ProxyService::CreateFixed("https://proxy:70"));
5678
5679 HttpRequestInfo request;
5680 request.method = "GET";
5681 request.url = GURL("https://www.google.com/");
5682 request.load_flags = 0;
5683
[email protected]9075f51c2013-08-15 17:53:545684 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5685 LOWEST));
[email protected]c10b20852013-05-15 21:29:205686 scoped_ptr<SpdyFrame> goaway(
5687 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295688 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065689 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:125690 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295691 };
5692
5693 static const char* const kExtraHeaders[] = {
5694 "location",
5695 "http://login.example.com/",
5696 };
[email protected]ff98d7f02012-03-22 21:44:195697 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025698 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295699 arraysize(kExtraHeaders)/2, 1));
5700 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065701 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5702 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:295703 };
5704
[email protected]dd54bd82012-07-19 23:44:575705 DelayedSocketData data(
5706 1, // wait for one write to finish before reading.
5707 data_reads, arraysize(data_reads),
5708 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065709 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025710 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295711
[email protected]bb88e1d32013-05-03 23:11:075712 session_deps_.socket_factory->AddSocketDataProvider(&data);
5713 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295714
[email protected]49639fa2011-12-20 23:22:415715 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295716
5717 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365718 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075719 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295720
[email protected]49639fa2011-12-20 23:22:415721 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295722 EXPECT_EQ(ERR_IO_PENDING, rv);
5723
5724 rv = callback.WaitForResult();
5725 EXPECT_EQ(OK, rv);
5726 const HttpResponseInfo* response = trans->GetResponseInfo();
5727
[email protected]fe2255a2011-09-20 19:37:505728 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295729
5730 EXPECT_EQ(302, response->headers->response_code());
5731 std::string url;
5732 EXPECT_TRUE(response->headers->IsRedirect(&url));
5733 EXPECT_EQ("http://login.example.com/", url);
5734}
5735
[email protected]4eddbc732012-08-09 05:40:175736// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025737TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175738 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075739 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295740 ProxyService::CreateFixed("https://proxy:70"));
5741
5742 HttpRequestInfo request;
5743 request.method = "GET";
5744 request.url = GURL("https://www.google.com/");
5745 request.load_flags = 0;
5746
5747 MockWrite data_writes[] = {
5748 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5749 "Host: www.google.com\r\n"
5750 "Proxy-Connection: keep-alive\r\n\r\n"),
5751 };
5752
5753 MockRead data_reads[] = {
5754 MockRead("HTTP/1.1 404 Not Found\r\n"),
5755 MockRead("Content-Length: 23\r\n\r\n"),
5756 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:065757 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295758 };
5759
5760 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5761 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065762 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295763
[email protected]bb88e1d32013-05-03 23:11:075764 session_deps_.socket_factory->AddSocketDataProvider(&data);
5765 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295766
[email protected]49639fa2011-12-20 23:22:415767 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295768
5769 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365770 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075771 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295772
[email protected]49639fa2011-12-20 23:22:415773 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295774 EXPECT_EQ(ERR_IO_PENDING, rv);
5775
5776 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175777 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295778
[email protected]4eddbc732012-08-09 05:40:175779 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295780}
5781
[email protected]4eddbc732012-08-09 05:40:175782// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025783TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175784 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075785 session_deps_.proxy_service.reset(
5786 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:295787
5788 HttpRequestInfo request;
5789 request.method = "GET";
5790 request.url = GURL("https://www.google.com/");
5791 request.load_flags = 0;
5792
[email protected]9075f51c2013-08-15 17:53:545793 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5794 LOWEST));
[email protected]c10b20852013-05-15 21:29:205795 scoped_ptr<SpdyFrame> rst(
5796 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295797 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065798 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175799 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295800 };
5801
5802 static const char* const kExtraHeaders[] = {
5803 "location",
5804 "http://login.example.com/",
5805 };
[email protected]ff98d7f02012-03-22 21:44:195806 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025807 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295808 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:195809 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:025810 spdy_util_.ConstructSpdyBodyFrame(
5811 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:295812 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065813 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5814 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175815 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:295816 };
5817
[email protected]dd54bd82012-07-19 23:44:575818 DelayedSocketData data(
5819 1, // wait for one write to finish before reading.
5820 data_reads, arraysize(data_reads),
5821 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065822 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025823 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295824
[email protected]bb88e1d32013-05-03 23:11:075825 session_deps_.socket_factory->AddSocketDataProvider(&data);
5826 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295827
[email protected]49639fa2011-12-20 23:22:415828 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295829
5830 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365831 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075832 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295833
[email protected]49639fa2011-12-20 23:22:415834 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295835 EXPECT_EQ(ERR_IO_PENDING, rv);
5836
5837 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175838 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295839
[email protected]4eddbc732012-08-09 05:40:175840 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295841}
5842
[email protected]0c5fb722012-02-28 11:50:355843// Test the request-challenge-retry sequence for basic auth, through
5844// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:025845TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:355846 HttpRequestInfo request;
5847 request.method = "GET";
5848 request.url = GURL("https://www.google.com/");
5849 // when the no authentication data flag is set.
5850 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
5851
5852 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075853 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205854 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:295855 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075856 session_deps_.net_log = log.bound().net_log();
5857 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:355858
5859 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:545860 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5861 LOWEST));
[email protected]c10b20852013-05-15 21:29:205862 scoped_ptr<SpdyFrame> rst(
5863 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:355864
5865 // After calling trans->RestartWithAuth(), this is the request we should
5866 // be issuing -- the final header line contains the credentials.
5867 const char* const kAuthCredentials[] = {
5868 "proxy-authorization", "Basic Zm9vOmJhcg==",
5869 };
[email protected]fba2dbde2013-05-24 16:09:015870 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:545871 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:355872 // fetch https://www.google.com/ via HTTP
5873 const char get[] = "GET / HTTP/1.1\r\n"
5874 "Host: www.google.com\r\n"
5875 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:195876 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:025877 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:355878
5879 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:205880 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:215881 CreateMockWrite(*rst, 4, ASYNC),
5882 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:205883 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:355884 };
5885
5886 // The proxy responds to the connect with a 407, using a persistent
5887 // connection.
5888 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:025889 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
5890 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:355891 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
5892 };
5893
[email protected]ff98d7f02012-03-22 21:44:195894 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:235895 spdy_util_.ConstructSpdyControlFrame(NULL,
5896 0,
5897 false,
5898 1,
5899 LOWEST,
5900 SYN_REPLY,
5901 CONTROL_FLAG_NONE,
5902 kAuthChallenge,
5903 arraysize(kAuthChallenge),
5904 0));
[email protected]0c5fb722012-02-28 11:50:355905
[email protected]23e482282013-06-14 16:08:025906 scoped_ptr<SpdyFrame> conn_resp(
5907 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:355908 const char resp[] = "HTTP/1.1 200 OK\r\n"
5909 "Content-Length: 5\r\n\r\n";
5910
[email protected]ff98d7f02012-03-22 21:44:195911 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025912 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:195913 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:025914 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:355915 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:205916 CreateMockRead(*conn_auth_resp, 2, ASYNC),
5917 CreateMockRead(*conn_resp, 6, ASYNC),
5918 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
5919 CreateMockRead(*wrapped_body, 10, ASYNC),
5920 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:355921 };
5922
[email protected]dd54bd82012-07-19 23:44:575923 OrderedSocketData spdy_data(
5924 spdy_reads, arraysize(spdy_reads),
5925 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075926 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:355927 // Negotiate SPDY to the proxy
5928 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:025929 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:075930 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:355931 // Vanilla SSL to the server
5932 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075933 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:355934
5935 TestCompletionCallback callback1;
5936
[email protected]262eec82013-03-19 21:01:365937 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:355939
5940 int rv = trans->Start(&request, callback1.callback(), log.bound());
5941 EXPECT_EQ(ERR_IO_PENDING, rv);
5942
5943 rv = callback1.WaitForResult();
5944 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:575945 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:355946 log.GetEntries(&entries);
5947 size_t pos = ExpectLogContainsSomewhere(
5948 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
5949 NetLog::PHASE_NONE);
5950 ExpectLogContainsSomewhere(
5951 entries, pos,
5952 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
5953 NetLog::PHASE_NONE);
5954
5955 const HttpResponseInfo* response = trans->GetResponseInfo();
5956 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505957 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:355958 EXPECT_EQ(407, response->headers->response_code());
5959 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5960 EXPECT_TRUE(response->auth_challenge.get() != NULL);
5961 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5962
5963 TestCompletionCallback callback2;
5964
5965 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
5966 callback2.callback());
5967 EXPECT_EQ(ERR_IO_PENDING, rv);
5968
5969 rv = callback2.WaitForResult();
5970 EXPECT_EQ(OK, rv);
5971
5972 response = trans->GetResponseInfo();
5973 ASSERT_TRUE(response != NULL);
5974
5975 EXPECT_TRUE(response->headers->IsKeepAlive());
5976 EXPECT_EQ(200, response->headers->response_code());
5977 EXPECT_EQ(5, response->headers->GetContentLength());
5978 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5979
5980 // The password prompt info should not be set.
5981 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5982
[email protected]029c83b62013-01-24 05:28:205983 LoadTimingInfo load_timing_info;
5984 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5985 TestLoadTimingNotReusedWithPac(load_timing_info,
5986 CONNECT_TIMING_HAS_SSL_TIMES);
5987
[email protected]0c5fb722012-02-28 11:50:355988 trans.reset();
5989 session->CloseAllConnections();
5990}
5991
[email protected]7c6f7ba2012-04-03 04:09:295992// Test that an explicitly trusted SPDY proxy can push a resource from an
5993// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:025994TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:295995 HttpRequestInfo request;
5996 HttpRequestInfo push_request;
5997
[email protected]7c6f7ba2012-04-03 04:09:295998 request.method = "GET";
5999 request.url = GURL("http://www.google.com/");
6000 push_request.method = "GET";
6001 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6002
[email protected]7c6f7ba2012-04-03 04:09:296003 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076004 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206005 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296006 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076007 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506008
6009 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076010 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506011
[email protected]bb88e1d32013-05-03 23:11:076012 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296013
[email protected]cdf8f7e72013-05-23 10:56:466014 scoped_ptr<SpdyFrame> stream1_syn(
6015 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296016
6017 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466018 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296019 };
6020
6021 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026022 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296023
6024 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026025 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296026
6027 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026028 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296029 0,
6030 2,
6031 1,
6032 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436033 const char kPushedData[] = "pushed";
6034 scoped_ptr<SpdyFrame> stream2_body(
6035 spdy_util_.ConstructSpdyBodyFrame(
6036 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296037
6038 MockRead spdy_reads[] = {
6039 CreateMockRead(*stream1_reply, 2, ASYNC),
6040 CreateMockRead(*stream2_syn, 3, ASYNC),
6041 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436042 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296043 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6044 };
6045
[email protected]dd54bd82012-07-19 23:44:576046 OrderedSocketData spdy_data(
6047 spdy_reads, arraysize(spdy_reads),
6048 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076049 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296050 // Negotiate SPDY to the proxy
6051 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026052 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076053 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296054
[email protected]262eec82013-03-19 21:01:366055 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506056 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296057 TestCompletionCallback callback;
6058 int rv = trans->Start(&request, callback.callback(), log.bound());
6059 EXPECT_EQ(ERR_IO_PENDING, rv);
6060
6061 rv = callback.WaitForResult();
6062 EXPECT_EQ(OK, rv);
6063 const HttpResponseInfo* response = trans->GetResponseInfo();
6064
[email protected]262eec82013-03-19 21:01:366065 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6067 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296068 EXPECT_EQ(ERR_IO_PENDING, rv);
6069
6070 rv = callback.WaitForResult();
6071 EXPECT_EQ(OK, rv);
6072 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6073
6074 ASSERT_TRUE(response != NULL);
6075 EXPECT_TRUE(response->headers->IsKeepAlive());
6076
6077 EXPECT_EQ(200, response->headers->response_code());
6078 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6079
6080 std::string response_data;
6081 rv = ReadTransaction(trans.get(), &response_data);
6082 EXPECT_EQ(OK, rv);
6083 EXPECT_EQ("hello!", response_data);
6084
[email protected]029c83b62013-01-24 05:28:206085 LoadTimingInfo load_timing_info;
6086 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6087 TestLoadTimingNotReusedWithPac(load_timing_info,
6088 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6089
[email protected]7c6f7ba2012-04-03 04:09:296090 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506091 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296092 EXPECT_EQ(200, push_response->headers->response_code());
6093
6094 rv = ReadTransaction(push_trans.get(), &response_data);
6095 EXPECT_EQ(OK, rv);
6096 EXPECT_EQ("pushed", response_data);
6097
[email protected]029c83b62013-01-24 05:28:206098 LoadTimingInfo push_load_timing_info;
6099 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6100 TestLoadTimingReusedWithPac(push_load_timing_info);
6101 // The transactions should share a socket ID, despite being for different
6102 // origins.
6103 EXPECT_EQ(load_timing_info.socket_log_id,
6104 push_load_timing_info.socket_log_id);
6105
[email protected]7c6f7ba2012-04-03 04:09:296106 trans.reset();
6107 push_trans.reset();
6108 session->CloseAllConnections();
6109}
6110
[email protected]8c843192012-04-05 07:15:006111// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026112TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006113 HttpRequestInfo request;
6114
6115 request.method = "GET";
6116 request.url = GURL("http://www.google.com/");
6117
[email protected]8c843192012-04-05 07:15:006118 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076119 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006120 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296121 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076122 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506123
6124 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076125 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506126
[email protected]bb88e1d32013-05-03 23:11:076127 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006128
[email protected]cdf8f7e72013-05-23 10:56:466129 scoped_ptr<SpdyFrame> stream1_syn(
6130 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006131
6132 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206133 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006134
6135 MockWrite spdy_writes[] = {
6136 CreateMockWrite(*stream1_syn, 1, ASYNC),
6137 CreateMockWrite(*push_rst, 4),
6138 };
6139
6140 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026141 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006142
6143 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026144 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006145
6146 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026147 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006148 0,
6149 2,
6150 1,
6151 "https://www.another-origin.com/foo.dat"));
6152
6153 MockRead spdy_reads[] = {
6154 CreateMockRead(*stream1_reply, 2, ASYNC),
6155 CreateMockRead(*stream2_syn, 3, ASYNC),
6156 CreateMockRead(*stream1_body, 5, ASYNC),
6157 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6158 };
6159
[email protected]dd54bd82012-07-19 23:44:576160 OrderedSocketData spdy_data(
6161 spdy_reads, arraysize(spdy_reads),
6162 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076163 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006164 // Negotiate SPDY to the proxy
6165 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026166 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076167 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006168
[email protected]262eec82013-03-19 21:01:366169 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506170 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006171 TestCompletionCallback callback;
6172 int rv = trans->Start(&request, callback.callback(), log.bound());
6173 EXPECT_EQ(ERR_IO_PENDING, rv);
6174
6175 rv = callback.WaitForResult();
6176 EXPECT_EQ(OK, rv);
6177 const HttpResponseInfo* response = trans->GetResponseInfo();
6178
6179 ASSERT_TRUE(response != NULL);
6180 EXPECT_TRUE(response->headers->IsKeepAlive());
6181
6182 EXPECT_EQ(200, response->headers->response_code());
6183 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6184
6185 std::string response_data;
6186 rv = ReadTransaction(trans.get(), &response_data);
6187 EXPECT_EQ(OK, rv);
6188 EXPECT_EQ("hello!", response_data);
6189
6190 trans.reset();
6191 session->CloseAllConnections();
6192}
6193
[email protected]2df19bb2010-08-25 20:13:466194// Test HTTPS connections to a site with a bad certificate, going through an
6195// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026196TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076197 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116198 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466199
6200 HttpRequestInfo request;
6201 request.method = "GET";
6202 request.url = GURL("https://www.google.com/");
6203 request.load_flags = 0;
6204
6205 // Attempt to fetch the URL from a server with a bad cert
6206 MockWrite bad_cert_writes[] = {
6207 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6208 "Host: www.google.com\r\n"
6209 "Proxy-Connection: keep-alive\r\n\r\n"),
6210 };
6211
6212 MockRead bad_cert_reads[] = {
6213 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066214 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466215 };
6216
6217 // Attempt to fetch the URL with a good cert
6218 MockWrite good_data_writes[] = {
6219 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6220 "Host: www.google.com\r\n"
6221 "Proxy-Connection: keep-alive\r\n\r\n"),
6222 MockWrite("GET / HTTP/1.1\r\n"
6223 "Host: www.google.com\r\n"
6224 "Connection: keep-alive\r\n\r\n"),
6225 };
6226
6227 MockRead good_cert_reads[] = {
6228 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6229 MockRead("HTTP/1.0 200 OK\r\n"),
6230 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6231 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066232 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466233 };
6234
6235 StaticSocketDataProvider ssl_bad_certificate(
6236 bad_cert_reads, arraysize(bad_cert_reads),
6237 bad_cert_writes, arraysize(bad_cert_writes));
6238 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6239 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066240 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6241 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466242
6243 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6245 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466247
6248 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6250 session_deps_.socket_factory->AddSocketDataProvider(&data);
6251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466252
[email protected]49639fa2011-12-20 23:22:416253 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466254
6255 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366256 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076257 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:466258
[email protected]49639fa2011-12-20 23:22:416259 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466260 EXPECT_EQ(ERR_IO_PENDING, rv);
6261
6262 rv = callback.WaitForResult();
6263 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6264
[email protected]49639fa2011-12-20 23:22:416265 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466266 EXPECT_EQ(ERR_IO_PENDING, rv);
6267
6268 rv = callback.WaitForResult();
6269 EXPECT_EQ(OK, rv);
6270
6271 const HttpResponseInfo* response = trans->GetResponseInfo();
6272
[email protected]fe2255a2011-09-20 19:37:506273 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466274 EXPECT_EQ(100, response->headers->GetContentLength());
6275}
6276
[email protected]23e482282013-06-14 16:08:026277TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426278 HttpRequestInfo request;
6279 request.method = "GET";
6280 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436281 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6282 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426283
[email protected]cb9bf6ca2011-01-28 13:15:276284 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366285 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076286 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276287
[email protected]1c773ea12009-04-28 19:58:426288 MockWrite data_writes[] = {
6289 MockWrite("GET / HTTP/1.1\r\n"
6290 "Host: www.google.com\r\n"
6291 "Connection: keep-alive\r\n"
6292 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6293 };
6294
6295 // Lastly, the server responds with the actual content.
6296 MockRead data_reads[] = {
6297 MockRead("HTTP/1.0 200 OK\r\n"),
6298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6299 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066300 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426301 };
6302
[email protected]31a2bfe2010-02-09 08:03:396303 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6304 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076305 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426306
[email protected]49639fa2011-12-20 23:22:416307 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426308
[email protected]49639fa2011-12-20 23:22:416309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426310 EXPECT_EQ(ERR_IO_PENDING, rv);
6311
6312 rv = callback.WaitForResult();
6313 EXPECT_EQ(OK, rv);
6314}
6315
[email protected]23e482282013-06-14 16:08:026316TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296317 HttpRequestInfo request;
6318 request.method = "GET";
6319 request.url = GURL("https://www.google.com/");
6320 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6321 "Chromium Ultra Awesome X Edition");
6322
[email protected]bb88e1d32013-05-03 23:11:076323 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:276324 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366325 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076326 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276327
[email protected]da81f132010-08-18 23:39:296328 MockWrite data_writes[] = {
6329 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6330 "Host: www.google.com\r\n"
6331 "Proxy-Connection: keep-alive\r\n"
6332 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6333 };
6334 MockRead data_reads[] = {
6335 // Return an error, so the transaction stops here (this test isn't
6336 // interested in the rest).
6337 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6338 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6339 MockRead("Proxy-Connection: close\r\n\r\n"),
6340 };
6341
6342 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6343 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076344 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296345
[email protected]49639fa2011-12-20 23:22:416346 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296347
[email protected]49639fa2011-12-20 23:22:416348 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296349 EXPECT_EQ(ERR_IO_PENDING, rv);
6350
6351 rv = callback.WaitForResult();
6352 EXPECT_EQ(OK, rv);
6353}
6354
[email protected]23e482282013-06-14 16:08:026355TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426356 HttpRequestInfo request;
6357 request.method = "GET";
6358 request.url = GURL("http://www.google.com/");
6359 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166360 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6361 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426362
[email protected]cb9bf6ca2011-01-28 13:15:276363 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366364 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076365 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276366
[email protected]1c773ea12009-04-28 19:58:426367 MockWrite data_writes[] = {
6368 MockWrite("GET / HTTP/1.1\r\n"
6369 "Host: www.google.com\r\n"
6370 "Connection: keep-alive\r\n"
6371 "Referer: http://the.previous.site.com/\r\n\r\n"),
6372 };
6373
6374 // Lastly, the server responds with the actual content.
6375 MockRead data_reads[] = {
6376 MockRead("HTTP/1.0 200 OK\r\n"),
6377 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6378 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066379 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426380 };
6381
[email protected]31a2bfe2010-02-09 08:03:396382 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6383 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426385
[email protected]49639fa2011-12-20 23:22:416386 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426387
[email protected]49639fa2011-12-20 23:22:416388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426389 EXPECT_EQ(ERR_IO_PENDING, rv);
6390
6391 rv = callback.WaitForResult();
6392 EXPECT_EQ(OK, rv);
6393}
6394
[email protected]23e482282013-06-14 16:08:026395TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426396 HttpRequestInfo request;
6397 request.method = "POST";
6398 request.url = GURL("http://www.google.com/");
6399
[email protected]cb9bf6ca2011-01-28 13:15:276400 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366401 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076402 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276403
[email protected]1c773ea12009-04-28 19:58:426404 MockWrite data_writes[] = {
6405 MockWrite("POST / HTTP/1.1\r\n"
6406 "Host: www.google.com\r\n"
6407 "Connection: keep-alive\r\n"
6408 "Content-Length: 0\r\n\r\n"),
6409 };
6410
6411 // Lastly, the server responds with the actual content.
6412 MockRead data_reads[] = {
6413 MockRead("HTTP/1.0 200 OK\r\n"),
6414 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6415 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066416 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426417 };
6418
[email protected]31a2bfe2010-02-09 08:03:396419 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6420 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076421 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426422
[email protected]49639fa2011-12-20 23:22:416423 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426424
[email protected]49639fa2011-12-20 23:22:416425 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426426 EXPECT_EQ(ERR_IO_PENDING, rv);
6427
6428 rv = callback.WaitForResult();
6429 EXPECT_EQ(OK, rv);
6430}
6431
[email protected]23e482282013-06-14 16:08:026432TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426433 HttpRequestInfo request;
6434 request.method = "PUT";
6435 request.url = GURL("http://www.google.com/");
6436
[email protected]cb9bf6ca2011-01-28 13:15:276437 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366438 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076439 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276440
[email protected]1c773ea12009-04-28 19:58:426441 MockWrite data_writes[] = {
6442 MockWrite("PUT / HTTP/1.1\r\n"
6443 "Host: www.google.com\r\n"
6444 "Connection: keep-alive\r\n"
6445 "Content-Length: 0\r\n\r\n"),
6446 };
6447
6448 // Lastly, the server responds with the actual content.
6449 MockRead data_reads[] = {
6450 MockRead("HTTP/1.0 200 OK\r\n"),
6451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6452 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066453 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426454 };
6455
[email protected]31a2bfe2010-02-09 08:03:396456 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6457 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076458 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426459
[email protected]49639fa2011-12-20 23:22:416460 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426461
[email protected]49639fa2011-12-20 23:22:416462 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426463 EXPECT_EQ(ERR_IO_PENDING, rv);
6464
6465 rv = callback.WaitForResult();
6466 EXPECT_EQ(OK, rv);
6467}
6468
[email protected]23e482282013-06-14 16:08:026469TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426470 HttpRequestInfo request;
6471 request.method = "HEAD";
6472 request.url = GURL("http://www.google.com/");
6473
[email protected]cb9bf6ca2011-01-28 13:15:276474 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366475 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076476 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276477
[email protected]1c773ea12009-04-28 19:58:426478 MockWrite data_writes[] = {
6479 MockWrite("HEAD / HTTP/1.1\r\n"
6480 "Host: www.google.com\r\n"
6481 "Connection: keep-alive\r\n"
6482 "Content-Length: 0\r\n\r\n"),
6483 };
6484
6485 // Lastly, the server responds with the actual content.
6486 MockRead data_reads[] = {
6487 MockRead("HTTP/1.0 200 OK\r\n"),
6488 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6489 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066490 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426491 };
6492
[email protected]31a2bfe2010-02-09 08:03:396493 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6494 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076495 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426496
[email protected]49639fa2011-12-20 23:22:416497 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426498
[email protected]49639fa2011-12-20 23:22:416499 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426500 EXPECT_EQ(ERR_IO_PENDING, rv);
6501
6502 rv = callback.WaitForResult();
6503 EXPECT_EQ(OK, rv);
6504}
6505
[email protected]23e482282013-06-14 16:08:026506TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426507 HttpRequestInfo request;
6508 request.method = "GET";
6509 request.url = GURL("http://www.google.com/");
6510 request.load_flags = LOAD_BYPASS_CACHE;
6511
[email protected]cb9bf6ca2011-01-28 13:15:276512 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366513 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076514 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276515
[email protected]1c773ea12009-04-28 19:58:426516 MockWrite data_writes[] = {
6517 MockWrite("GET / HTTP/1.1\r\n"
6518 "Host: www.google.com\r\n"
6519 "Connection: keep-alive\r\n"
6520 "Pragma: no-cache\r\n"
6521 "Cache-Control: no-cache\r\n\r\n"),
6522 };
6523
6524 // Lastly, the server responds with the actual content.
6525 MockRead data_reads[] = {
6526 MockRead("HTTP/1.0 200 OK\r\n"),
6527 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6528 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066529 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426530 };
6531
[email protected]31a2bfe2010-02-09 08:03:396532 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6533 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076534 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426535
[email protected]49639fa2011-12-20 23:22:416536 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426537
[email protected]49639fa2011-12-20 23:22:416538 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426539 EXPECT_EQ(ERR_IO_PENDING, rv);
6540
6541 rv = callback.WaitForResult();
6542 EXPECT_EQ(OK, rv);
6543}
6544
[email protected]23e482282013-06-14 16:08:026545TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426546 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426547 HttpRequestInfo request;
6548 request.method = "GET";
6549 request.url = GURL("http://www.google.com/");
6550 request.load_flags = LOAD_VALIDATE_CACHE;
6551
[email protected]cb9bf6ca2011-01-28 13:15:276552 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366553 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076554 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276555
[email protected]1c773ea12009-04-28 19:58:426556 MockWrite data_writes[] = {
6557 MockWrite("GET / HTTP/1.1\r\n"
6558 "Host: www.google.com\r\n"
6559 "Connection: keep-alive\r\n"
6560 "Cache-Control: max-age=0\r\n\r\n"),
6561 };
6562
6563 // Lastly, the server responds with the actual content.
6564 MockRead data_reads[] = {
6565 MockRead("HTTP/1.0 200 OK\r\n"),
6566 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6567 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066568 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426569 };
6570
[email protected]31a2bfe2010-02-09 08:03:396571 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6572 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076573 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426574
[email protected]49639fa2011-12-20 23:22:416575 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426576
[email protected]49639fa2011-12-20 23:22:416577 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426578 EXPECT_EQ(ERR_IO_PENDING, rv);
6579
6580 rv = callback.WaitForResult();
6581 EXPECT_EQ(OK, rv);
6582}
6583
[email protected]23e482282013-06-14 16:08:026584TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426585 HttpRequestInfo request;
6586 request.method = "GET";
6587 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436588 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426589
[email protected]cb9bf6ca2011-01-28 13:15:276590 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366591 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076592 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276593
[email protected]1c773ea12009-04-28 19:58:426594 MockWrite data_writes[] = {
6595 MockWrite("GET / HTTP/1.1\r\n"
6596 "Host: www.google.com\r\n"
6597 "Connection: keep-alive\r\n"
6598 "FooHeader: Bar\r\n\r\n"),
6599 };
6600
6601 // Lastly, the server responds with the actual content.
6602 MockRead data_reads[] = {
6603 MockRead("HTTP/1.0 200 OK\r\n"),
6604 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6605 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066606 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426607 };
6608
[email protected]31a2bfe2010-02-09 08:03:396609 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6610 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076611 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426612
[email protected]49639fa2011-12-20 23:22:416613 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426614
[email protected]49639fa2011-12-20 23:22:416615 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426616 EXPECT_EQ(ERR_IO_PENDING, rv);
6617
6618 rv = callback.WaitForResult();
6619 EXPECT_EQ(OK, rv);
6620}
6621
[email protected]23e482282013-06-14 16:08:026622TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476623 HttpRequestInfo request;
6624 request.method = "GET";
6625 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436626 request.extra_headers.SetHeader("referer", "www.foo.com");
6627 request.extra_headers.SetHeader("hEllo", "Kitty");
6628 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476629
[email protected]cb9bf6ca2011-01-28 13:15:276630 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366631 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076632 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276633
[email protected]270c6412010-03-29 22:02:476634 MockWrite data_writes[] = {
6635 MockWrite("GET / HTTP/1.1\r\n"
6636 "Host: www.google.com\r\n"
6637 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166638 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476639 "hEllo: Kitty\r\n"
6640 "FoO: bar\r\n\r\n"),
6641 };
6642
6643 // Lastly, the server responds with the actual content.
6644 MockRead data_reads[] = {
6645 MockRead("HTTP/1.0 200 OK\r\n"),
6646 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6647 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066648 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476649 };
6650
6651 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6652 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076653 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:476654
[email protected]49639fa2011-12-20 23:22:416655 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:476656
[email protected]49639fa2011-12-20 23:22:416657 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:476658 EXPECT_EQ(ERR_IO_PENDING, rv);
6659
6660 rv = callback.WaitForResult();
6661 EXPECT_EQ(OK, rv);
6662}
6663
[email protected]23e482282013-06-14 16:08:026664TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276665 HttpRequestInfo request;
6666 request.method = "GET";
6667 request.url = GURL("http://www.google.com/");
6668 request.load_flags = 0;
6669
[email protected]bb88e1d32013-05-03 23:11:076670 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206671 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6672 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076673 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026674
6675 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366676 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076677 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026678
[email protected]3cd17242009-06-23 02:59:026679 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6680 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6681
6682 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066683 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026684 MockWrite("GET / HTTP/1.1\r\n"
6685 "Host: www.google.com\r\n"
6686 "Connection: keep-alive\r\n\r\n")
6687 };
6688
6689 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066690 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:026691 MockRead("HTTP/1.0 200 OK\r\n"),
6692 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6693 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066694 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026695 };
6696
[email protected]31a2bfe2010-02-09 08:03:396697 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6698 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076699 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026700
[email protected]49639fa2011-12-20 23:22:416701 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026702
[email protected]49639fa2011-12-20 23:22:416703 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026704 EXPECT_EQ(ERR_IO_PENDING, rv);
6705
6706 rv = callback.WaitForResult();
6707 EXPECT_EQ(OK, rv);
6708
6709 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506710 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026711
[email protected]029c83b62013-01-24 05:28:206712 LoadTimingInfo load_timing_info;
6713 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6714 TestLoadTimingNotReusedWithPac(load_timing_info,
6715 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6716
[email protected]3cd17242009-06-23 02:59:026717 std::string response_text;
6718 rv = ReadTransaction(trans.get(), &response_text);
6719 EXPECT_EQ(OK, rv);
6720 EXPECT_EQ("Payload", response_text);
6721}
6722
[email protected]23e482282013-06-14 16:08:026723TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276724 HttpRequestInfo request;
6725 request.method = "GET";
6726 request.url = GURL("https://www.google.com/");
6727 request.load_flags = 0;
6728
[email protected]bb88e1d32013-05-03 23:11:076729 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206730 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6731 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076732 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026733
6734 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366735 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076736 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026737
[email protected]3cd17242009-06-23 02:59:026738 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6739 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6740
6741 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066742 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:356743 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026744 MockWrite("GET / HTTP/1.1\r\n"
6745 "Host: www.google.com\r\n"
6746 "Connection: keep-alive\r\n\r\n")
6747 };
6748
6749 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016750 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6751 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:356752 MockRead("HTTP/1.0 200 OK\r\n"),
6753 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6754 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066755 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356756 };
6757
[email protected]31a2bfe2010-02-09 08:03:396758 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6759 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076760 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356761
[email protected]8ddf8322012-02-23 18:08:066762 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076763 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:356764
[email protected]49639fa2011-12-20 23:22:416765 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356766
[email protected]49639fa2011-12-20 23:22:416767 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356768 EXPECT_EQ(ERR_IO_PENDING, rv);
6769
6770 rv = callback.WaitForResult();
6771 EXPECT_EQ(OK, rv);
6772
[email protected]029c83b62013-01-24 05:28:206773 LoadTimingInfo load_timing_info;
6774 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6775 TestLoadTimingNotReusedWithPac(load_timing_info,
6776 CONNECT_TIMING_HAS_SSL_TIMES);
6777
[email protected]e0c27be2009-07-15 13:09:356778 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506779 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356780
6781 std::string response_text;
6782 rv = ReadTransaction(trans.get(), &response_text);
6783 EXPECT_EQ(OK, rv);
6784 EXPECT_EQ("Payload", response_text);
6785}
6786
[email protected]23e482282013-06-14 16:08:026787TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:206788 HttpRequestInfo request;
6789 request.method = "GET";
6790 request.url = GURL("http://www.google.com/");
6791 request.load_flags = 0;
6792
[email protected]bb88e1d32013-05-03 23:11:076793 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206794 ProxyService::CreateFixed("socks4://myproxy:1080"));
6795 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076796 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:206797
6798 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366799 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076800 CreateSession(&session_deps_)));
[email protected]029c83b62013-01-24 05:28:206801
6802 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6803 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6804
6805 MockWrite data_writes[] = {
6806 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6807 MockWrite("GET / HTTP/1.1\r\n"
6808 "Host: www.google.com\r\n"
6809 "Connection: keep-alive\r\n\r\n")
6810 };
6811
6812 MockRead data_reads[] = {
6813 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6814 MockRead("HTTP/1.0 200 OK\r\n"),
6815 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6816 MockRead("Payload"),
6817 MockRead(SYNCHRONOUS, OK)
6818 };
6819
6820 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6821 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076822 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:206823
6824 TestCompletionCallback callback;
6825
6826 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6827 EXPECT_EQ(ERR_IO_PENDING, rv);
6828
6829 rv = callback.WaitForResult();
6830 EXPECT_EQ(OK, rv);
6831
6832 const HttpResponseInfo* response = trans->GetResponseInfo();
6833 ASSERT_TRUE(response != NULL);
6834
6835 LoadTimingInfo load_timing_info;
6836 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6837 TestLoadTimingNotReused(load_timing_info,
6838 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6839
6840 std::string response_text;
6841 rv = ReadTransaction(trans.get(), &response_text);
6842 EXPECT_EQ(OK, rv);
6843 EXPECT_EQ("Payload", response_text);
6844}
6845
[email protected]23e482282013-06-14 16:08:026846TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276847 HttpRequestInfo request;
6848 request.method = "GET";
6849 request.url = GURL("http://www.google.com/");
6850 request.load_flags = 0;
6851
[email protected]bb88e1d32013-05-03 23:11:076852 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206853 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6854 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076855 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356856
6857 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366858 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076859 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356860
[email protected]e0c27be2009-07-15 13:09:356861 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6862 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376863 const char kSOCKS5OkRequest[] = {
6864 0x05, // Version
6865 0x01, // Command (CONNECT)
6866 0x00, // Reserved.
6867 0x03, // Address type (DOMAINNAME).
6868 0x0E, // Length of domain (14)
6869 // Domain string:
6870 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6871 0x00, 0x50, // 16-bit port (80)
6872 };
[email protected]e0c27be2009-07-15 13:09:356873 const char kSOCKS5OkResponse[] =
6874 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
6875
6876 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066877 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6878 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:356879 MockWrite("GET / HTTP/1.1\r\n"
6880 "Host: www.google.com\r\n"
6881 "Connection: keep-alive\r\n\r\n")
6882 };
6883
6884 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016885 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6886 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:356887 MockRead("HTTP/1.0 200 OK\r\n"),
6888 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6889 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066890 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356891 };
6892
[email protected]31a2bfe2010-02-09 08:03:396893 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6894 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076895 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356896
[email protected]49639fa2011-12-20 23:22:416897 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356898
[email protected]49639fa2011-12-20 23:22:416899 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356900 EXPECT_EQ(ERR_IO_PENDING, rv);
6901
6902 rv = callback.WaitForResult();
6903 EXPECT_EQ(OK, rv);
6904
6905 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506906 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356907
[email protected]029c83b62013-01-24 05:28:206908 LoadTimingInfo load_timing_info;
6909 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6910 TestLoadTimingNotReusedWithPac(load_timing_info,
6911 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6912
[email protected]e0c27be2009-07-15 13:09:356913 std::string response_text;
6914 rv = ReadTransaction(trans.get(), &response_text);
6915 EXPECT_EQ(OK, rv);
6916 EXPECT_EQ("Payload", response_text);
6917}
6918
[email protected]23e482282013-06-14 16:08:026919TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276920 HttpRequestInfo request;
6921 request.method = "GET";
6922 request.url = GURL("https://www.google.com/");
6923 request.load_flags = 0;
6924
[email protected]bb88e1d32013-05-03 23:11:076925 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206926 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6927 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076928 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356929
6930 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366931 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076932 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356933
[email protected]e0c27be2009-07-15 13:09:356934 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6935 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376936 const unsigned char kSOCKS5OkRequest[] = {
6937 0x05, // Version
6938 0x01, // Command (CONNECT)
6939 0x00, // Reserved.
6940 0x03, // Address type (DOMAINNAME).
6941 0x0E, // Length of domain (14)
6942 // Domain string:
6943 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6944 0x01, 0xBB, // 16-bit port (443)
6945 };
6946
[email protected]e0c27be2009-07-15 13:09:356947 const char kSOCKS5OkResponse[] =
6948 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
6949
6950 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066951 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6952 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:356953 arraysize(kSOCKS5OkRequest)),
6954 MockWrite("GET / HTTP/1.1\r\n"
6955 "Host: www.google.com\r\n"
6956 "Connection: keep-alive\r\n\r\n")
6957 };
6958
6959 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016960 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6961 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:026962 MockRead("HTTP/1.0 200 OK\r\n"),
6963 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6964 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066965 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026966 };
6967
[email protected]31a2bfe2010-02-09 08:03:396968 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6969 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076970 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026971
[email protected]8ddf8322012-02-23 18:08:066972 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076973 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:026974
[email protected]49639fa2011-12-20 23:22:416975 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026976
[email protected]49639fa2011-12-20 23:22:416977 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026978 EXPECT_EQ(ERR_IO_PENDING, rv);
6979
6980 rv = callback.WaitForResult();
6981 EXPECT_EQ(OK, rv);
6982
6983 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506984 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026985
[email protected]029c83b62013-01-24 05:28:206986 LoadTimingInfo load_timing_info;
6987 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6988 TestLoadTimingNotReusedWithPac(load_timing_info,
6989 CONNECT_TIMING_HAS_SSL_TIMES);
6990
[email protected]3cd17242009-06-23 02:59:026991 std::string response_text;
6992 rv = ReadTransaction(trans.get(), &response_text);
6993 EXPECT_EQ(OK, rv);
6994 EXPECT_EQ("Payload", response_text);
6995}
6996
[email protected]448d4ca52012-03-04 04:12:236997namespace {
6998
[email protected]04e5be32009-06-26 20:00:316999// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067000
7001struct GroupNameTest {
7002 std::string proxy_server;
7003 std::string url;
7004 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187005 bool ssl;
[email protected]2d731a32010-04-29 01:04:067006};
7007
7008scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437009 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077010 SpdySessionDependencies* session_deps_) {
7011 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067012
[email protected]30d4c022013-07-18 22:58:167013 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537014 session->http_server_properties();
7015 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067016 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437017 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067018
7019 return session;
7020}
7021
7022int GroupNameTransactionHelper(
7023 const std::string& url,
7024 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067025 HttpRequestInfo request;
7026 request.method = "GET";
7027 request.url = GURL(url);
7028 request.load_flags = 0;
7029
[email protected]262eec82013-03-19 21:01:367030 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507031 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277032
[email protected]49639fa2011-12-20 23:22:417033 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067034
7035 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417036 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067037}
7038
[email protected]448d4ca52012-03-04 04:12:237039} // namespace
7040
[email protected]23e482282013-06-14 16:08:027041TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067042 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317043 {
[email protected]2d731a32010-04-29 01:04:067044 "", // unused
[email protected]04e5be32009-06-26 20:00:317045 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547046 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187047 false,
[email protected]2ff8b312010-04-26 22:20:547048 },
7049 {
[email protected]2d731a32010-04-29 01:04:067050 "", // unused
[email protected]2ff8b312010-04-26 22:20:547051 "http://[2001:1418:13:1::25]/direct",
7052 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187053 false,
[email protected]04e5be32009-06-26 20:00:317054 },
[email protected]04e5be32009-06-26 20:00:317055
7056 // SSL Tests
7057 {
[email protected]2d731a32010-04-29 01:04:067058 "", // unused
[email protected]04e5be32009-06-26 20:00:317059 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027060 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187061 true,
[email protected]04e5be32009-06-26 20:00:317062 },
7063 {
[email protected]2d731a32010-04-29 01:04:067064 "", // unused
7065 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027066 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187067 true,
[email protected]04e5be32009-06-26 20:00:317068 },
7069 {
[email protected]2d731a32010-04-29 01:04:067070 "", // unused
[email protected]2ff8b312010-04-26 22:20:547071 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027072 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187073 true,
[email protected]2ff8b312010-04-26 22:20:547074 },
[email protected]2d731a32010-04-29 01:04:067075 };
[email protected]2ff8b312010-04-26 22:20:547076
[email protected]8e6441ca2010-08-19 05:56:387077 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067078
7079 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077080 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027081 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067082 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437083 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067084
7085 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287086 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7087 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137088 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347089 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027090 MockClientSocketPoolManager* mock_pool_manager =
7091 new MockClientSocketPoolManager;
7092 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7093 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7094 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067095
7096 EXPECT_EQ(ERR_IO_PENDING,
7097 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187098 if (tests[i].ssl)
7099 EXPECT_EQ(tests[i].expected_group_name,
7100 ssl_conn_pool->last_group_name_received());
7101 else
7102 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287103 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067104 }
7105
[email protected]2d731a32010-04-29 01:04:067106}
7107
[email protected]23e482282013-06-14 16:08:027108TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067109 const GroupNameTest tests[] = {
7110 {
7111 "http_proxy",
7112 "http://www.google.com/http_proxy_normal",
7113 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187114 false,
[email protected]2d731a32010-04-29 01:04:067115 },
7116
7117 // SSL Tests
7118 {
7119 "http_proxy",
7120 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027121 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187122 true,
[email protected]2d731a32010-04-29 01:04:067123 },
[email protected]af3490e2010-10-16 21:02:297124
[email protected]9faeded92010-04-29 20:03:057125 {
7126 "http_proxy",
7127 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027128 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187129 true,
[email protected]9faeded92010-04-29 20:03:057130 },
[email protected]45499252013-01-23 17:12:567131
7132 {
7133 "http_proxy",
7134 "ftp://ftp.google.com/http_proxy_normal",
7135 "ftp/ftp.google.com:21",
7136 false,
7137 },
[email protected]2d731a32010-04-29 01:04:067138 };
7139
[email protected]8e6441ca2010-08-19 05:56:387140 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067141
7142 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077143 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027144 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067145 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437146 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067147
7148 HttpNetworkSessionPeer peer(session);
7149
[email protected]e60e47a2010-07-14 03:37:187150 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137151 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347152 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137153 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347154 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027155
7156 MockClientSocketPoolManager* mock_pool_manager =
7157 new MockClientSocketPoolManager;
7158 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7159 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7160 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067161
7162 EXPECT_EQ(ERR_IO_PENDING,
7163 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187164 if (tests[i].ssl)
7165 EXPECT_EQ(tests[i].expected_group_name,
7166 ssl_conn_pool->last_group_name_received());
7167 else
7168 EXPECT_EQ(tests[i].expected_group_name,
7169 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067170 }
[email protected]2d731a32010-04-29 01:04:067171}
7172
[email protected]23e482282013-06-14 16:08:027173TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067174 const GroupNameTest tests[] = {
7175 {
7176 "socks4://socks_proxy:1080",
7177 "http://www.google.com/socks4_direct",
7178 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187179 false,
[email protected]2d731a32010-04-29 01:04:067180 },
7181 {
7182 "socks5://socks_proxy:1080",
7183 "http://www.google.com/socks5_direct",
7184 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187185 false,
[email protected]2d731a32010-04-29 01:04:067186 },
7187
7188 // SSL Tests
7189 {
7190 "socks4://socks_proxy:1080",
7191 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027192 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187193 true,
[email protected]2d731a32010-04-29 01:04:067194 },
7195 {
7196 "socks5://socks_proxy:1080",
7197 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027198 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187199 true,
[email protected]2d731a32010-04-29 01:04:067200 },
[email protected]af3490e2010-10-16 21:02:297201
[email protected]9faeded92010-04-29 20:03:057202 {
7203 "socks4://socks_proxy:1080",
7204 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027205 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187206 true,
[email protected]9faeded92010-04-29 20:03:057207 },
[email protected]04e5be32009-06-26 20:00:317208 };
7209
[email protected]8e6441ca2010-08-19 05:56:387210 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547211
[email protected]04e5be32009-06-26 20:00:317212 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077213 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027214 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067215 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437216 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027217
[email protected]2d731a32010-04-29 01:04:067218 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317219
[email protected]e60e47a2010-07-14 03:37:187220 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137221 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347222 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137223 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347224 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027225
7226 MockClientSocketPoolManager* mock_pool_manager =
7227 new MockClientSocketPoolManager;
7228 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7229 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7230 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]04e5be32009-06-26 20:00:317231
[email protected]262eec82013-03-19 21:01:367232 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317234
[email protected]2d731a32010-04-29 01:04:067235 EXPECT_EQ(ERR_IO_PENDING,
7236 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187237 if (tests[i].ssl)
7238 EXPECT_EQ(tests[i].expected_group_name,
7239 ssl_conn_pool->last_group_name_received());
7240 else
7241 EXPECT_EQ(tests[i].expected_group_name,
7242 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317243 }
7244}
7245
[email protected]23e482282013-06-14 16:08:027246TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277247 HttpRequestInfo request;
7248 request.method = "GET";
7249 request.url = GURL("http://www.google.com/");
7250
[email protected]bb88e1d32013-05-03 23:11:077251 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007252 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327253
[email protected]69719062010-01-05 20:09:217254 // This simulates failure resolving all hostnames; that means we will fail
7255 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077256 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327257
[email protected]9172a982009-06-06 00:30:257258 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367259 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077260 CreateSession(&session_deps_)));
[email protected]9172a982009-06-06 00:30:257261
[email protected]49639fa2011-12-20 23:22:417262 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257263
[email protected]49639fa2011-12-20 23:22:417264 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257265 EXPECT_EQ(ERR_IO_PENDING, rv);
7266
[email protected]9172a982009-06-06 00:30:257267 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017268 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257269}
7270
[email protected]685af592010-05-11 19:31:247271// Base test to make sure that when the load flags for a request specify to
7272// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027273void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077274 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277275 // Issue a request, asking to bypass the cache(s).
7276 HttpRequestInfo request;
7277 request.method = "GET";
7278 request.load_flags = load_flags;
7279 request.url = GURL("http://www.google.com/");
7280
[email protected]a2c2fb92009-07-18 07:31:047281 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077282 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327283
[email protected]262eec82013-03-19 21:01:367284 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077285 CreateSession(&session_deps_)));
[email protected]3b9cca42009-06-16 01:08:287286
[email protected]6e78dfb2011-07-28 21:34:477287 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287288 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297289 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077290 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107291 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7292 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417293 &addrlist,
7294 callback.callback(),
7295 NULL,
7296 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477297 EXPECT_EQ(ERR_IO_PENDING, rv);
7298 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287299 EXPECT_EQ(OK, rv);
7300
7301 // Verify that it was added to host cache, by doing a subsequent async lookup
7302 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077303 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107304 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7305 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417306 &addrlist,
7307 callback.callback(),
7308 NULL,
7309 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327310 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287311
7312 // Inject a failure the next time that "www.google.com" is resolved. This way
7313 // we can tell if the next lookup hit the cache, or the "network".
7314 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077315 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287316
7317 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7318 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067319 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397320 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077321 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287322
[email protected]3b9cca42009-06-16 01:08:287323 // Run the request.
[email protected]49639fa2011-12-20 23:22:417324 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287325 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417326 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287327
7328 // If we bypassed the cache, we would have gotten a failure while resolving
7329 // "www.google.com".
7330 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7331}
7332
[email protected]685af592010-05-11 19:31:247333// There are multiple load flags that should trigger the host cache bypass.
7334// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027335TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247336 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7337}
7338
[email protected]23e482282013-06-14 16:08:027339TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247340 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7341}
7342
[email protected]23e482282013-06-14 16:08:027343TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247344 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7345}
7346
[email protected]0877e3d2009-10-17 22:29:577347// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027348TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]bb88e1d32013-05-03 23:11:077349 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577350
7351 HttpRequestInfo request;
7352 request.method = "GET";
7353 request.url = GURL("http://www.foo.com/");
7354 request.load_flags = 0;
7355
7356 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067357 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577358 };
[email protected]31a2bfe2010-02-09 08:03:397359 StaticSocketDataProvider data(NULL, 0,
7360 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077361 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577362
[email protected]49639fa2011-12-20 23:22:417363 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577364
7365 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367366 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077367 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577368
[email protected]49639fa2011-12-20 23:22:417369 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577370 EXPECT_EQ(ERR_IO_PENDING, rv);
7371
7372 rv = callback.WaitForResult();
7373 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7374}
7375
7376// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027377TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]bb88e1d32013-05-03 23:11:077378 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577379
7380 HttpRequestInfo request;
7381 request.method = "GET";
7382 request.url = GURL("http://www.foo.com/");
7383 request.load_flags = 0;
7384
7385 MockRead data_reads[] = {
7386 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067387 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577388 };
7389
[email protected]31a2bfe2010-02-09 08:03:397390 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077391 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577392
[email protected]49639fa2011-12-20 23:22:417393 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577394
7395 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367396 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077397 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577398
[email protected]49639fa2011-12-20 23:22:417399 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577400 EXPECT_EQ(ERR_IO_PENDING, rv);
7401
7402 rv = callback.WaitForResult();
7403 EXPECT_EQ(OK, rv);
7404
7405 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507406 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577407
[email protected]90499482013-06-01 00:39:507408 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577409 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7410
7411 std::string response_data;
7412 rv = ReadTransaction(trans.get(), &response_data);
7413 EXPECT_EQ(OK, rv);
7414 EXPECT_EQ("", response_data);
7415}
7416
7417// Make sure that a dropped connection while draining the body for auth
7418// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027419TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]bb88e1d32013-05-03 23:11:077420 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577421
7422 HttpRequestInfo request;
7423 request.method = "GET";
7424 request.url = GURL("http://www.google.com/");
7425 request.load_flags = 0;
7426
7427 MockWrite data_writes1[] = {
7428 MockWrite("GET / HTTP/1.1\r\n"
7429 "Host: www.google.com\r\n"
7430 "Connection: keep-alive\r\n\r\n"),
7431 };
7432
7433 MockRead data_reads1[] = {
7434 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7435 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7436 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7437 MockRead("Content-Length: 14\r\n\r\n"),
7438 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067439 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577440 };
7441
[email protected]31a2bfe2010-02-09 08:03:397442 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7443 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077444 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577445
7446 // After calling trans->RestartWithAuth(), this is the request we should
7447 // be issuing -- the final header line contains the credentials.
7448 MockWrite data_writes2[] = {
7449 MockWrite("GET / HTTP/1.1\r\n"
7450 "Host: www.google.com\r\n"
7451 "Connection: keep-alive\r\n"
7452 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7453 };
7454
7455 // Lastly, the server responds with the actual content.
7456 MockRead data_reads2[] = {
7457 MockRead("HTTP/1.1 200 OK\r\n"),
7458 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7459 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067460 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577461 };
7462
[email protected]31a2bfe2010-02-09 08:03:397463 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7464 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077465 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]0877e3d2009-10-17 22:29:577466
[email protected]49639fa2011-12-20 23:22:417467 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577468
[email protected]262eec82013-03-19 21:01:367469 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507470 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507471
[email protected]49639fa2011-12-20 23:22:417472 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577473 EXPECT_EQ(ERR_IO_PENDING, rv);
7474
7475 rv = callback1.WaitForResult();
7476 EXPECT_EQ(OK, rv);
7477
7478 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507479 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047480 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577481
[email protected]49639fa2011-12-20 23:22:417482 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577483
[email protected]49639fa2011-12-20 23:22:417484 rv = trans->RestartWithAuth(
7485 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577486 EXPECT_EQ(ERR_IO_PENDING, rv);
7487
7488 rv = callback2.WaitForResult();
7489 EXPECT_EQ(OK, rv);
7490
7491 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507492 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577493 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7494 EXPECT_EQ(100, response->headers->GetContentLength());
7495}
7496
7497// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027498TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077499 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577500
7501 HttpRequestInfo request;
7502 request.method = "GET";
7503 request.url = GURL("https://www.google.com/");
7504 request.load_flags = 0;
7505
7506 MockRead proxy_reads[] = {
7507 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067508 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577509 };
7510
[email protected]31a2bfe2010-02-09 08:03:397511 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067512 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577513
[email protected]bb88e1d32013-05-03 23:11:077514 session_deps_.socket_factory->AddSocketDataProvider(&data);
7515 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577516
[email protected]49639fa2011-12-20 23:22:417517 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577518
[email protected]bb88e1d32013-05-03 23:11:077519 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577520
7521 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367522 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077523 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577524
[email protected]49639fa2011-12-20 23:22:417525 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577526 EXPECT_EQ(ERR_IO_PENDING, rv);
7527
7528 rv = callback.WaitForResult();
7529 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7530}
7531
[email protected]23e482282013-06-14 16:08:027532TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467533 HttpRequestInfo request;
7534 request.method = "GET";
7535 request.url = GURL("http://www.google.com/");
7536 request.load_flags = 0;
7537
[email protected]cb9bf6ca2011-01-28 13:15:277538 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367539 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077540 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:277541
[email protected]e22e1362009-11-23 21:31:127542 MockRead data_reads[] = {
7543 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067544 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127545 };
[email protected]9492e4a2010-02-24 00:58:467546
7547 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077548 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467549
[email protected]49639fa2011-12-20 23:22:417550 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467551
[email protected]49639fa2011-12-20 23:22:417552 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467553 EXPECT_EQ(ERR_IO_PENDING, rv);
7554
7555 EXPECT_EQ(OK, callback.WaitForResult());
7556
7557 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507558 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467559
[email protected]90499482013-06-01 00:39:507560 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467561 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7562
7563 std::string response_data;
7564 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237565 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127566}
7567
[email protected]23e482282013-06-14 16:08:027568TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157569 base::FilePath temp_file_path;
[email protected]95d88ffe2010-02-04 21:25:337570 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
7571 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217572 UploadFileElementReader::ScopedOverridingContentLengthForTests
7573 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337574
[email protected]b2d26cfd2012-12-11 10:36:067575 ScopedVector<UploadElementReader> element_readers;
7576 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367577 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7578 temp_file_path,
7579 0,
7580 kuint64max,
7581 base::Time()));
[email protected]96c77a72013-09-24 09:49:207582 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277583
7584 HttpRequestInfo request;
7585 request.method = "POST";
7586 request.url = GURL("http://www.google.com/upload");
7587 request.upload_data_stream = &upload_data_stream;
7588 request.load_flags = 0;
7589
[email protected]329b68b2012-11-14 17:54:277590 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367591 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077592 CreateSession(&session_deps_)));
[email protected]95d88ffe2010-02-04 21:25:337593
7594 MockRead data_reads[] = {
7595 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7596 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067597 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337598 };
[email protected]31a2bfe2010-02-09 08:03:397599 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077600 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337601
[email protected]49639fa2011-12-20 23:22:417602 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337603
[email protected]49639fa2011-12-20 23:22:417604 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337605 EXPECT_EQ(ERR_IO_PENDING, rv);
7606
7607 rv = callback.WaitForResult();
7608 EXPECT_EQ(OK, rv);
7609
7610 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507611 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337612
[email protected]90499482013-06-01 00:39:507613 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337614 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7615
7616 std::string response_data;
7617 rv = ReadTransaction(trans.get(), &response_data);
7618 EXPECT_EQ(OK, rv);
7619 EXPECT_EQ("hello world", response_data);
7620
[email protected]dd3aa792013-07-16 19:10:237621 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:337622}
7623
[email protected]23e482282013-06-14 16:08:027624TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157625 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367626 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7627 std::string temp_file_content("Unreadable file.");
7628 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
7629 temp_file_content.length()));
7630 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7631
[email protected]b2d26cfd2012-12-11 10:36:067632 ScopedVector<UploadElementReader> element_readers;
7633 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367634 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7635 temp_file,
7636 0,
7637 kuint64max,
7638 base::Time()));
[email protected]96c77a72013-09-24 09:49:207639 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277640
7641 HttpRequestInfo request;
7642 request.method = "POST";
7643 request.url = GURL("http://www.google.com/upload");
7644 request.upload_data_stream = &upload_data_stream;
7645 request.load_flags = 0;
7646
7647 // If we try to upload an unreadable file, the network stack should report
7648 // the file size as zero and upload zero bytes for that file.
[email protected]329b68b2012-11-14 17:54:277649 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367650 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077651 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367652
7653 MockRead data_reads[] = {
7654 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067655 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367656 };
7657 MockWrite data_writes[] = {
7658 MockWrite("POST /upload HTTP/1.1\r\n"
7659 "Host: www.google.com\r\n"
7660 "Connection: keep-alive\r\n"
7661 "Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067662 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367663 };
7664 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7665 arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077666 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367667
[email protected]49639fa2011-12-20 23:22:417668 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:367669
[email protected]49639fa2011-12-20 23:22:417670 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367671 EXPECT_EQ(ERR_IO_PENDING, rv);
7672
7673 rv = callback.WaitForResult();
7674 EXPECT_EQ(OK, rv);
7675
7676 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507677 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507678 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367679 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7680
[email protected]dd3aa792013-07-16 19:10:237681 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367682}
7683
[email protected]23e482282013-06-14 16:08:027684TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
[email protected]6cdfd7f2013-02-08 20:40:157685 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367686 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7687 std::string temp_file_contents("Unreadable file.");
7688 std::string unreadable_contents(temp_file_contents.length(), '\0');
7689 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
7690 temp_file_contents.length()));
7691
[email protected]b2d26cfd2012-12-11 10:36:067692 ScopedVector<UploadElementReader> element_readers;
7693 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367694 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7695 temp_file,
7696 0,
7697 kuint64max,
7698 base::Time()));
[email protected]96c77a72013-09-24 09:49:207699 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277700
7701 HttpRequestInfo request;
7702 request.method = "POST";
7703 request.url = GURL("http://www.google.com/upload");
7704 request.upload_data_stream = &upload_data_stream;
7705 request.load_flags = 0;
7706
[email protected]329b68b2012-11-14 17:54:277707 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367708 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077709 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367710
7711 MockRead data_reads[] = {
7712 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7713 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7714 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
7715
7716 MockRead("HTTP/1.1 200 OK\r\n"),
7717 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067718 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367719 };
7720 MockWrite data_writes[] = {
7721 MockWrite("POST /upload HTTP/1.1\r\n"
7722 "Host: www.google.com\r\n"
7723 "Connection: keep-alive\r\n"
7724 "Content-Length: 16\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067725 MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
[email protected]6624b4622010-03-29 19:58:367726
7727 MockWrite("POST /upload HTTP/1.1\r\n"
7728 "Host: www.google.com\r\n"
7729 "Connection: keep-alive\r\n"
[email protected]d98961652012-09-11 20:27:217730 "Content-Length: 0\r\n"
[email protected]6624b4622010-03-29 19:58:367731 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067732 MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
7733 temp_file_contents.length()),
7734 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367735 };
7736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7737 arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367739
[email protected]49639fa2011-12-20 23:22:417740 TestCompletionCallback callback1;
[email protected]6624b4622010-03-29 19:58:367741
[email protected]49639fa2011-12-20 23:22:417742 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367743 EXPECT_EQ(ERR_IO_PENDING, rv);
7744
7745 rv = callback1.WaitForResult();
7746 EXPECT_EQ(OK, rv);
7747
7748 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:047749 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507750 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367751 EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
[email protected]79cb5c12011-09-12 13:12:047752 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]6624b4622010-03-29 19:58:367753
7754 // Now make the file unreadable and try again.
7755 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7756
[email protected]49639fa2011-12-20 23:22:417757 TestCompletionCallback callback2;
[email protected]6624b4622010-03-29 19:58:367758
[email protected]49639fa2011-12-20 23:22:417759 rv = trans->RestartWithAuth(
7760 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]6624b4622010-03-29 19:58:367761 EXPECT_EQ(ERR_IO_PENDING, rv);
7762
7763 rv = callback2.WaitForResult();
7764 EXPECT_EQ(OK, rv);
7765
7766 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507767 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507768 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367769 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7770 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7771
[email protected]dd3aa792013-07-16 19:10:237772 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367773}
7774
[email protected]02cad5d2013-10-02 08:14:037775TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
7776 class FakeUploadElementReader : public UploadElementReader {
7777 public:
7778 FakeUploadElementReader() {}
7779 virtual ~FakeUploadElementReader() {}
7780
7781 const CompletionCallback& callback() const { return callback_; }
7782
7783 // UploadElementReader overrides:
7784 virtual int Init(const CompletionCallback& callback) OVERRIDE {
7785 callback_ = callback;
7786 return ERR_IO_PENDING;
7787 }
7788 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
7789 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
7790 virtual int Read(IOBuffer* buf,
7791 int buf_length,
7792 const CompletionCallback& callback) OVERRIDE {
7793 return ERR_FAILED;
7794 }
7795
7796 private:
7797 CompletionCallback callback_;
7798 };
7799
7800 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
7801 ScopedVector<UploadElementReader> element_readers;
7802 element_readers.push_back(fake_reader);
7803 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7804
7805 HttpRequestInfo request;
7806 request.method = "POST";
7807 request.url = GURL("http://www.google.com/upload");
7808 request.upload_data_stream = &upload_data_stream;
7809 request.load_flags = 0;
7810
7811 scoped_ptr<HttpTransaction> trans(
7812 new HttpNetworkTransaction(DEFAULT_PRIORITY,
7813 CreateSession(&session_deps_)));
7814
7815 StaticSocketDataProvider data;
7816 session_deps_.socket_factory->AddSocketDataProvider(&data);
7817
7818 TestCompletionCallback callback;
7819 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7820 EXPECT_EQ(ERR_IO_PENDING, rv);
7821 base::MessageLoop::current()->RunUntilIdle();
7822
7823 // Transaction is pending on request body initialization.
7824 ASSERT_FALSE(fake_reader->callback().is_null());
7825
7826 // Return Init()'s result after the transaction gets destroyed.
7827 trans.reset();
7828 fake_reader->callback().Run(OK); // Should not crash.
7829}
7830
[email protected]aeefc9e82010-02-19 16:18:277831// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:027832TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:277833
7834 HttpRequestInfo request;
7835 request.method = "GET";
7836 request.url = GURL("http://www.google.com/");
7837 request.load_flags = 0;
7838
7839 // First transaction will request a resource and receive a Basic challenge
7840 // with realm="first_realm".
7841 MockWrite data_writes1[] = {
7842 MockWrite("GET / HTTP/1.1\r\n"
7843 "Host: www.google.com\r\n"
7844 "Connection: keep-alive\r\n"
7845 "\r\n"),
7846 };
7847 MockRead data_reads1[] = {
7848 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7849 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7850 "\r\n"),
7851 };
7852
7853 // After calling trans->RestartWithAuth(), provide an Authentication header
7854 // for first_realm. The server will reject and provide a challenge with
7855 // second_realm.
7856 MockWrite data_writes2[] = {
7857 MockWrite("GET / HTTP/1.1\r\n"
7858 "Host: www.google.com\r\n"
7859 "Connection: keep-alive\r\n"
7860 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7861 "\r\n"),
7862 };
7863 MockRead data_reads2[] = {
7864 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7865 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7866 "\r\n"),
7867 };
7868
7869 // This again fails, and goes back to first_realm. Make sure that the
7870 // entry is removed from cache.
7871 MockWrite data_writes3[] = {
7872 MockWrite("GET / HTTP/1.1\r\n"
7873 "Host: www.google.com\r\n"
7874 "Connection: keep-alive\r\n"
7875 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
7876 "\r\n"),
7877 };
7878 MockRead data_reads3[] = {
7879 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7880 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7881 "\r\n"),
7882 };
7883
7884 // Try one last time (with the correct password) and get the resource.
7885 MockWrite data_writes4[] = {
7886 MockWrite("GET / HTTP/1.1\r\n"
7887 "Host: www.google.com\r\n"
7888 "Connection: keep-alive\r\n"
7889 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
7890 "\r\n"),
7891 };
7892 MockRead data_reads4[] = {
7893 MockRead("HTTP/1.1 200 OK\r\n"
7894 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:507895 "Content-Length: 5\r\n"
7896 "\r\n"
7897 "hello"),
[email protected]aeefc9e82010-02-19 16:18:277898 };
7899
7900 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7901 data_writes1, arraysize(data_writes1));
7902 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7903 data_writes2, arraysize(data_writes2));
7904 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7905 data_writes3, arraysize(data_writes3));
7906 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
7907 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:077908 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7909 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7910 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7911 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:277912
[email protected]49639fa2011-12-20 23:22:417913 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:277914
[email protected]0b0bf032010-09-21 18:08:507915 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367916 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077917 CreateSession(&session_deps_)));
[email protected]0b0bf032010-09-21 18:08:507918
[email protected]aeefc9e82010-02-19 16:18:277919 // Issue the first request with Authorize headers. There should be a
7920 // password prompt for first_realm waiting to be filled in after the
7921 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417922 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:277923 EXPECT_EQ(ERR_IO_PENDING, rv);
7924 rv = callback1.WaitForResult();
7925 EXPECT_EQ(OK, rv);
7926 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507927 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047928 const AuthChallengeInfo* challenge = response->auth_challenge.get();
7929 ASSERT_FALSE(challenge == NULL);
7930 EXPECT_FALSE(challenge->is_proxy);
7931 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7932 EXPECT_EQ("first_realm", challenge->realm);
7933 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277934
7935 // Issue the second request with an incorrect password. There should be a
7936 // password prompt for second_realm waiting to be filled in after the
7937 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417938 TestCompletionCallback callback2;
7939 rv = trans->RestartWithAuth(
7940 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:277941 EXPECT_EQ(ERR_IO_PENDING, rv);
7942 rv = callback2.WaitForResult();
7943 EXPECT_EQ(OK, rv);
7944 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507945 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047946 challenge = response->auth_challenge.get();
7947 ASSERT_FALSE(challenge == NULL);
7948 EXPECT_FALSE(challenge->is_proxy);
7949 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7950 EXPECT_EQ("second_realm", challenge->realm);
7951 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277952
7953 // Issue the third request with another incorrect password. There should be
7954 // a password prompt for first_realm waiting to be filled in. If the password
7955 // prompt is not present, it indicates that the HttpAuthCacheEntry for
7956 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:417957 TestCompletionCallback callback3;
7958 rv = trans->RestartWithAuth(
7959 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:277960 EXPECT_EQ(ERR_IO_PENDING, rv);
7961 rv = callback3.WaitForResult();
7962 EXPECT_EQ(OK, rv);
7963 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507964 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047965 challenge = response->auth_challenge.get();
7966 ASSERT_FALSE(challenge == NULL);
7967 EXPECT_FALSE(challenge->is_proxy);
7968 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7969 EXPECT_EQ("first_realm", challenge->realm);
7970 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277971
7972 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:417973 TestCompletionCallback callback4;
7974 rv = trans->RestartWithAuth(
7975 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:277976 EXPECT_EQ(ERR_IO_PENDING, rv);
7977 rv = callback4.WaitForResult();
7978 EXPECT_EQ(OK, rv);
7979 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507980 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:277981 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7982}
7983
[email protected]23e482282013-06-14 16:08:027984TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:037985 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:237986 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:427987
[email protected]8a0fc822013-06-27 20:52:437988 std::string alternate_protocol_http_header =
7989 GetAlternateProtocolHttpHeader();
7990
[email protected]564b4912010-03-09 16:30:427991 MockRead data_reads[] = {
7992 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:437993 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:427994 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067995 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:427996 };
7997
7998 HttpRequestInfo request;
7999 request.method = "GET";
8000 request.url = GURL("http://www.google.com/");
8001 request.load_flags = 0;
8002
8003 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8004
[email protected]bb88e1d32013-05-03 23:11:078005 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428006
[email protected]49639fa2011-12-20 23:22:418007 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428008
[email protected]bb88e1d32013-05-03 23:11:078009 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368010 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508011 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428012
[email protected]49639fa2011-12-20 23:22:418013 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428014 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538015
[email protected]2fbaecf22010-07-22 22:20:358016 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]17291a022011-10-10 07:32:538017 const HttpServerProperties& http_server_properties =
8018 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428019 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538020 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428021
8022 EXPECT_EQ(OK, callback.WaitForResult());
8023
8024 const HttpResponseInfo* response = trans->GetResponseInfo();
8025 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508026 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428027 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538028 EXPECT_FALSE(response->was_fetched_via_spdy);
8029 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428030
8031 std::string response_data;
8032 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8033 EXPECT_EQ("hello world", response_data);
8034
[email protected]17291a022011-10-10 07:32:538035 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8036 const PortAlternateProtocolPair alternate =
8037 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8038 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428039 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438040 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428041 EXPECT_TRUE(expected_alternate.Equals(alternate));
8042}
8043
[email protected]23e482282013-06-14 16:08:028044TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238045 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388046 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428047
8048 HttpRequestInfo request;
8049 request.method = "GET";
8050 request.url = GURL("http://www.google.com/");
8051 request.load_flags = 0;
8052
[email protected]d973e99a2012-02-17 21:02:368053 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428054 StaticSocketDataProvider first_data;
8055 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078056 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428057
8058 MockRead data_reads[] = {
8059 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8060 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068061 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428062 };
8063 StaticSocketDataProvider second_data(
8064 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078065 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428066
[email protected]bb88e1d32013-05-03 23:11:078067 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428068
[email protected]30d4c022013-07-18 22:58:168069 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538070 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118071 // Port must be < 1024, or the header will be ignored (since initial port was
8072 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538073 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118074 HostPortPair::FromURL(request.url),
8075 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438076 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428077
[email protected]262eec82013-03-19 21:01:368078 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418080 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428081
[email protected]49639fa2011-12-20 23:22:418082 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428083 EXPECT_EQ(ERR_IO_PENDING, rv);
8084 EXPECT_EQ(OK, callback.WaitForResult());
8085
8086 const HttpResponseInfo* response = trans->GetResponseInfo();
8087 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508088 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428089 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8090
8091 std::string response_data;
8092 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8093 EXPECT_EQ("hello world", response_data);
8094
[email protected]17291a022011-10-10 07:32:538095 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118096 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538097 const PortAlternateProtocolPair alternate =
8098 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118099 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538100 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428101}
8102
[email protected]23e482282013-06-14 16:08:028103TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238104 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118105 // Ensure that we're not allowed to redirect traffic via an alternate
8106 // protocol to an unrestricted (port >= 1024) when the original traffic was
8107 // on a restricted port (port < 1024). Ensure that we can redirect in all
8108 // other cases.
8109 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118110
8111 HttpRequestInfo restricted_port_request;
8112 restricted_port_request.method = "GET";
8113 restricted_port_request.url = GURL("http://www.google.com:1023/");
8114 restricted_port_request.load_flags = 0;
8115
[email protected]d973e99a2012-02-17 21:02:368116 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118117 StaticSocketDataProvider first_data;
8118 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078119 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118120
8121 MockRead data_reads[] = {
8122 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8123 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068124 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118125 };
8126 StaticSocketDataProvider second_data(
8127 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078128 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118129
[email protected]bb88e1d32013-05-03 23:11:078130 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118131
[email protected]30d4c022013-07-18 22:58:168132 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538133 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118134 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538135 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118136 HostPortPair::FromURL(restricted_port_request.url),
8137 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438138 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118139
[email protected]262eec82013-03-19 21:01:368140 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418142 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118143
[email protected]49639fa2011-12-20 23:22:418144 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368145 &restricted_port_request,
8146 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118147 EXPECT_EQ(ERR_IO_PENDING, rv);
8148 // Invalid change to unrestricted port should fail.
8149 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198150}
[email protected]3912662a32011-10-04 00:51:118151
[email protected]23e482282013-06-14 16:08:028152TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198153 AlternateProtocolPortRestrictedPermitted) {
8154 // Ensure that we're allowed to redirect traffic via an alternate
8155 // protocol to an unrestricted (port >= 1024) when the original traffic was
8156 // on a restricted port (port < 1024) if we set
8157 // enable_user_alternate_protocol_ports.
8158
8159 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078160 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198161
8162 HttpRequestInfo restricted_port_request;
8163 restricted_port_request.method = "GET";
8164 restricted_port_request.url = GURL("http://www.google.com:1023/");
8165 restricted_port_request.load_flags = 0;
8166
8167 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8168 StaticSocketDataProvider first_data;
8169 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078170 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198171
8172 MockRead data_reads[] = {
8173 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8174 MockRead("hello world"),
8175 MockRead(ASYNC, OK),
8176 };
8177 StaticSocketDataProvider second_data(
8178 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078179 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198180
[email protected]bb88e1d32013-05-03 23:11:078181 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198182
[email protected]30d4c022013-07-18 22:58:168183 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198184 session->http_server_properties();
8185 const int kUnrestrictedAlternatePort = 1024;
8186 http_server_properties->SetAlternateProtocol(
8187 HostPortPair::FromURL(restricted_port_request.url),
8188 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438189 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198190
[email protected]262eec82013-03-19 21:01:368191 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508192 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198193 TestCompletionCallback callback;
8194
8195 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368196 &restricted_port_request,
8197 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198198 // Change to unrestricted port should succeed.
8199 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118200}
8201
[email protected]23e482282013-06-14 16:08:028202TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238203 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118204 // Ensure that we're not allowed to redirect traffic via an alternate
8205 // protocol to an unrestricted (port >= 1024) when the original traffic was
8206 // on a restricted port (port < 1024). Ensure that we can redirect in all
8207 // other cases.
8208 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118209
8210 HttpRequestInfo restricted_port_request;
8211 restricted_port_request.method = "GET";
8212 restricted_port_request.url = GURL("http://www.google.com:1023/");
8213 restricted_port_request.load_flags = 0;
8214
[email protected]d973e99a2012-02-17 21:02:368215 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118216 StaticSocketDataProvider first_data;
8217 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078218 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118219
8220 MockRead data_reads[] = {
8221 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8222 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068223 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118224 };
8225 StaticSocketDataProvider second_data(
8226 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078227 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118228
[email protected]bb88e1d32013-05-03 23:11:078229 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118230
[email protected]30d4c022013-07-18 22:58:168231 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538232 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118233 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538234 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118235 HostPortPair::FromURL(restricted_port_request.url),
8236 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438237 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118238
[email protected]262eec82013-03-19 21:01:368239 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418241 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118242
[email protected]49639fa2011-12-20 23:22:418243 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368244 &restricted_port_request,
8245 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118246 EXPECT_EQ(ERR_IO_PENDING, rv);
8247 // Valid change to restricted port should pass.
8248 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118249}
8250
[email protected]23e482282013-06-14 16:08:028251TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238252 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118253 // Ensure that we're not allowed to redirect traffic via an alternate
8254 // protocol to an unrestricted (port >= 1024) when the original traffic was
8255 // on a restricted port (port < 1024). Ensure that we can redirect in all
8256 // other cases.
8257 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118258
8259 HttpRequestInfo unrestricted_port_request;
8260 unrestricted_port_request.method = "GET";
8261 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8262 unrestricted_port_request.load_flags = 0;
8263
[email protected]d973e99a2012-02-17 21:02:368264 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118265 StaticSocketDataProvider first_data;
8266 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078267 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118268
8269 MockRead data_reads[] = {
8270 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8271 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068272 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118273 };
8274 StaticSocketDataProvider second_data(
8275 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078276 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118277
[email protected]bb88e1d32013-05-03 23:11:078278 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118279
[email protected]30d4c022013-07-18 22:58:168280 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538281 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118282 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538283 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118284 HostPortPair::FromURL(unrestricted_port_request.url),
8285 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438286 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118287
[email protected]262eec82013-03-19 21:01:368288 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508289 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418290 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118291
[email protected]49639fa2011-12-20 23:22:418292 int rv = trans->Start(
8293 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118294 EXPECT_EQ(ERR_IO_PENDING, rv);
8295 // Valid change to restricted port should pass.
8296 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118297}
8298
[email protected]23e482282013-06-14 16:08:028299TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238300 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118301 // Ensure that we're not allowed to redirect traffic via an alternate
8302 // protocol to an unrestricted (port >= 1024) when the original traffic was
8303 // on a restricted port (port < 1024). Ensure that we can redirect in all
8304 // other cases.
8305 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118306
8307 HttpRequestInfo unrestricted_port_request;
8308 unrestricted_port_request.method = "GET";
8309 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8310 unrestricted_port_request.load_flags = 0;
8311
[email protected]d973e99a2012-02-17 21:02:368312 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118313 StaticSocketDataProvider first_data;
8314 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078315 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118316
8317 MockRead data_reads[] = {
8318 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8319 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068320 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118321 };
8322 StaticSocketDataProvider second_data(
8323 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078324 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118325
[email protected]bb88e1d32013-05-03 23:11:078326 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118327
[email protected]30d4c022013-07-18 22:58:168328 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538329 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118330 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538331 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118332 HostPortPair::FromURL(unrestricted_port_request.url),
8333 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438334 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118335
[email protected]262eec82013-03-19 21:01:368336 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508337 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418338 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118339
[email protected]49639fa2011-12-20 23:22:418340 int rv = trans->Start(
8341 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118342 EXPECT_EQ(ERR_IO_PENDING, rv);
8343 // Valid change to an unrestricted port should pass.
8344 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118345}
8346
[email protected]23e482282013-06-14 16:08:028347TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238348 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028349 // Ensure that we're not allowed to redirect traffic via an alternate
8350 // protocol to an unsafe port, and that we resume the second
8351 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8352 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028353
8354 HttpRequestInfo request;
8355 request.method = "GET";
8356 request.url = GURL("http://www.google.com/");
8357 request.load_flags = 0;
8358
8359 // The alternate protocol request will error out before we attempt to connect,
8360 // so only the standard HTTP request will try to connect.
8361 MockRead data_reads[] = {
8362 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8363 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068364 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028365 };
8366 StaticSocketDataProvider data(
8367 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078368 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028369
[email protected]bb88e1d32013-05-03 23:11:078370 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028371
[email protected]30d4c022013-07-18 22:58:168372 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028373 session->http_server_properties();
8374 const int kUnsafePort = 7;
8375 http_server_properties->SetAlternateProtocol(
8376 HostPortPair::FromURL(request.url),
8377 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438378 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028379
[email protected]262eec82013-03-19 21:01:368380 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028382 TestCompletionCallback callback;
8383
8384 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8385 EXPECT_EQ(ERR_IO_PENDING, rv);
8386 // The HTTP request should succeed.
8387 EXPECT_EQ(OK, callback.WaitForResult());
8388
8389 // Disable alternate protocol before the asserts.
8390 HttpStreamFactory::set_use_alternate_protocols(false);
8391
8392 const HttpResponseInfo* response = trans->GetResponseInfo();
8393 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508394 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028395 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8396
8397 std::string response_data;
8398 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8399 EXPECT_EQ("hello world", response_data);
8400}
8401
[email protected]23e482282013-06-14 16:08:028402TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388403 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038404 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548405
8406 HttpRequestInfo request;
8407 request.method = "GET";
8408 request.url = GURL("http://www.google.com/");
8409 request.load_flags = 0;
8410
[email protected]8a0fc822013-06-27 20:52:438411 std::string alternate_protocol_http_header =
8412 GetAlternateProtocolHttpHeader();
8413
[email protected]2ff8b312010-04-26 22:20:548414 MockRead data_reads[] = {
8415 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438416 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548417 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178418 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8419 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548420 };
8421
8422 StaticSocketDataProvider first_transaction(
8423 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078424 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548425
[email protected]8ddf8322012-02-23 18:08:068426 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028427 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548429
[email protected]cdf8f7e72013-05-23 10:56:468430 scoped_ptr<SpdyFrame> req(
8431 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138432 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548433
[email protected]23e482282013-06-14 16:08:028434 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8435 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548436 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138437 CreateMockRead(*resp),
8438 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068439 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548440 };
8441
[email protected]dd54bd82012-07-19 23:44:578442 DelayedSocketData spdy_data(
8443 1, // wait for one write to finish before reading.
8444 spdy_reads, arraysize(spdy_reads),
8445 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078446 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548447
[email protected]d973e99a2012-02-17 21:02:368448 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558449 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8450 NULL, 0, NULL, 0);
8451 hanging_non_alternate_protocol_socket.set_connect_data(
8452 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078453 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558454 &hanging_non_alternate_protocol_socket);
8455
[email protected]49639fa2011-12-20 23:22:418456 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548457
[email protected]bb88e1d32013-05-03 23:11:078458 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368459 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508460 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548461
[email protected]49639fa2011-12-20 23:22:418462 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548463 EXPECT_EQ(ERR_IO_PENDING, rv);
8464 EXPECT_EQ(OK, callback.WaitForResult());
8465
8466 const HttpResponseInfo* response = trans->GetResponseInfo();
8467 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508468 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548469 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8470
8471 std::string response_data;
8472 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8473 EXPECT_EQ("hello world", response_data);
8474
[email protected]90499482013-06-01 00:39:508475 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548476
[email protected]49639fa2011-12-20 23:22:418477 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548478 EXPECT_EQ(ERR_IO_PENDING, rv);
8479 EXPECT_EQ(OK, callback.WaitForResult());
8480
8481 response = trans->GetResponseInfo();
8482 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508483 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548484 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538485 EXPECT_TRUE(response->was_fetched_via_spdy);
8486 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548487
8488 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8489 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548490}
8491
[email protected]23e482282013-06-14 16:08:028492TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558493 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038494 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558495
8496 HttpRequestInfo request;
8497 request.method = "GET";
8498 request.url = GURL("http://www.google.com/");
8499 request.load_flags = 0;
8500
[email protected]8a0fc822013-06-27 20:52:438501 std::string alternate_protocol_http_header =
8502 GetAlternateProtocolHttpHeader();
8503
[email protected]2d6728692011-03-12 01:39:558504 MockRead data_reads[] = {
8505 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438506 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558507 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178508 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068509 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558510 };
8511
8512 StaticSocketDataProvider first_transaction(
8513 data_reads, arraysize(data_reads), NULL, 0);
8514 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078515 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558516
[email protected]d973e99a2012-02-17 21:02:368517 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558518 StaticSocketDataProvider hanging_socket(
8519 NULL, 0, NULL, 0);
8520 hanging_socket.set_connect_data(never_finishing_connect);
8521 // Socket 2 and 3 are the hanging Alternate-Protocol and
8522 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078523 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8524 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558525
[email protected]8ddf8322012-02-23 18:08:068526 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028527 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078528 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558529
[email protected]cdf8f7e72013-05-23 10:56:468530 scoped_ptr<SpdyFrame> req1(
8531 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8532 scoped_ptr<SpdyFrame> req2(
8533 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558534 MockWrite spdy_writes[] = {
8535 CreateMockWrite(*req1),
8536 CreateMockWrite(*req2),
8537 };
[email protected]23e482282013-06-14 16:08:028538 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8539 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8540 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8541 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558542 MockRead spdy_reads[] = {
8543 CreateMockRead(*resp1),
8544 CreateMockRead(*data1),
8545 CreateMockRead(*resp2),
8546 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068547 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558548 };
8549
[email protected]dd54bd82012-07-19 23:44:578550 DelayedSocketData spdy_data(
8551 2, // wait for writes to finish before reading.
8552 spdy_reads, arraysize(spdy_reads),
8553 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558554 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078555 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558556
8557 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078558 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558559
[email protected]bb88e1d32013-05-03 23:11:078560 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418561 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508562 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558563
[email protected]49639fa2011-12-20 23:22:418564 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558565 EXPECT_EQ(ERR_IO_PENDING, rv);
8566 EXPECT_EQ(OK, callback1.WaitForResult());
8567
8568 const HttpResponseInfo* response = trans1.GetResponseInfo();
8569 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508570 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558571 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8572
8573 std::string response_data;
8574 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8575 EXPECT_EQ("hello world", response_data);
8576
[email protected]49639fa2011-12-20 23:22:418577 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508578 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418579 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558580 EXPECT_EQ(ERR_IO_PENDING, rv);
8581
[email protected]49639fa2011-12-20 23:22:418582 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508583 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418584 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558585 EXPECT_EQ(ERR_IO_PENDING, rv);
8586
8587 EXPECT_EQ(OK, callback2.WaitForResult());
8588 EXPECT_EQ(OK, callback3.WaitForResult());
8589
8590 response = trans2.GetResponseInfo();
8591 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508592 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558593 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8594 EXPECT_TRUE(response->was_fetched_via_spdy);
8595 EXPECT_TRUE(response->was_npn_negotiated);
8596 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8597 EXPECT_EQ("hello!", response_data);
8598
8599 response = trans3.GetResponseInfo();
8600 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508601 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558602 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8603 EXPECT_TRUE(response->was_fetched_via_spdy);
8604 EXPECT_TRUE(response->was_npn_negotiated);
8605 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8606 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558607}
8608
[email protected]23e482282013-06-14 16:08:028609TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558610 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038611 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558612
8613 HttpRequestInfo request;
8614 request.method = "GET";
8615 request.url = GURL("http://www.google.com/");
8616 request.load_flags = 0;
8617
[email protected]8a0fc822013-06-27 20:52:438618 std::string alternate_protocol_http_header =
8619 GetAlternateProtocolHttpHeader();
8620
[email protected]2d6728692011-03-12 01:39:558621 MockRead data_reads[] = {
8622 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438623 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558624 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178625 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068626 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558627 };
8628
8629 StaticSocketDataProvider first_transaction(
8630 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078631 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558632
[email protected]8ddf8322012-02-23 18:08:068633 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028634 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078635 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558636
[email protected]d973e99a2012-02-17 21:02:368637 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558638 StaticSocketDataProvider hanging_alternate_protocol_socket(
8639 NULL, 0, NULL, 0);
8640 hanging_alternate_protocol_socket.set_connect_data(
8641 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078642 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558643 &hanging_alternate_protocol_socket);
8644
8645 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078646 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558647
[email protected]49639fa2011-12-20 23:22:418648 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558649
[email protected]bb88e1d32013-05-03 23:11:078650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368651 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558653
[email protected]49639fa2011-12-20 23:22:418654 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558655 EXPECT_EQ(ERR_IO_PENDING, rv);
8656 EXPECT_EQ(OK, callback.WaitForResult());
8657
8658 const HttpResponseInfo* response = trans->GetResponseInfo();
8659 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508660 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558661 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8662
8663 std::string response_data;
8664 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8665 EXPECT_EQ("hello world", response_data);
8666
[email protected]90499482013-06-01 00:39:508667 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558668
[email protected]49639fa2011-12-20 23:22:418669 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558670 EXPECT_EQ(ERR_IO_PENDING, rv);
8671 EXPECT_EQ(OK, callback.WaitForResult());
8672
8673 response = trans->GetResponseInfo();
8674 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508675 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558676 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8677 EXPECT_FALSE(response->was_fetched_via_spdy);
8678 EXPECT_FALSE(response->was_npn_negotiated);
8679
8680 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8681 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558682}
8683
[email protected]631f1322010-04-30 17:59:118684class CapturingProxyResolver : public ProxyResolver {
8685 public:
8686 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8687 virtual ~CapturingProxyResolver() {}
8688
8689 virtual int GetProxyForURL(const GURL& url,
8690 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318691 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118692 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168693 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408694 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8695 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428696 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118697 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428698 return OK;
[email protected]631f1322010-04-30 17:59:118699 }
8700
[email protected]46fadfd2013-02-06 09:40:168701 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118702 NOTREACHED();
8703 }
8704
[email protected]f2c971f2011-11-08 00:33:178705 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8706 NOTREACHED();
8707 return LOAD_STATE_IDLE;
8708 }
8709
[email protected]46fadfd2013-02-06 09:40:168710 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408711 NOTREACHED();
8712 }
8713
[email protected]24476402010-07-20 20:55:178714 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168715 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428716 return OK;
[email protected]631f1322010-04-30 17:59:118717 }
8718
[email protected]24476402010-07-20 20:55:178719 const std::vector<GURL>& resolved() const { return resolved_; }
8720
8721 private:
[email protected]631f1322010-04-30 17:59:118722 std::vector<GURL> resolved_;
8723
8724 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8725};
8726
[email protected]23e482282013-06-14 16:08:028727TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238728 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388729 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038730 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118731
8732 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428733 proxy_config.set_auto_detect(true);
8734 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118735
[email protected]631f1322010-04-30 17:59:118736 CapturingProxyResolver* capturing_proxy_resolver =
8737 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078738 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388739 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8740 NULL));
[email protected]029c83b62013-01-24 05:28:208741 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078742 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118743
8744 HttpRequestInfo request;
8745 request.method = "GET";
8746 request.url = GURL("http://www.google.com/");
8747 request.load_flags = 0;
8748
[email protected]8a0fc822013-06-27 20:52:438749 std::string alternate_protocol_http_header =
8750 GetAlternateProtocolHttpHeader();
8751
[email protected]631f1322010-04-30 17:59:118752 MockRead data_reads[] = {
8753 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438754 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118755 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178756 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068757 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118758 };
8759
8760 StaticSocketDataProvider first_transaction(
8761 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078762 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:118763
[email protected]8ddf8322012-02-23 18:08:068764 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028765 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:118767
[email protected]cdf8f7e72013-05-23 10:56:468768 scoped_ptr<SpdyFrame> req(
8769 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:118770 MockWrite spdy_writes[] = {
8771 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8772 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:428773 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:468774 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:118775 };
8776
[email protected]d911f1b2010-05-05 22:39:428777 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8778
[email protected]23e482282013-06-14 16:08:028779 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8780 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:118781 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068782 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:138783 CreateMockRead(*resp.get(), 4), // 2, 4
8784 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:068785 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:118786 };
8787
[email protected]dd54bd82012-07-19 23:44:578788 OrderedSocketData spdy_data(
8789 spdy_reads, arraysize(spdy_reads),
8790 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078791 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:118792
[email protected]d973e99a2012-02-17 21:02:368793 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558794 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8795 NULL, 0, NULL, 0);
8796 hanging_non_alternate_protocol_socket.set_connect_data(
8797 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078798 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558799 &hanging_non_alternate_protocol_socket);
8800
[email protected]49639fa2011-12-20 23:22:418801 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:118802
[email protected]bb88e1d32013-05-03 23:11:078803 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368804 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118806
[email protected]49639fa2011-12-20 23:22:418807 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118808 EXPECT_EQ(ERR_IO_PENDING, rv);
8809 EXPECT_EQ(OK, callback.WaitForResult());
8810
8811 const HttpResponseInfo* response = trans->GetResponseInfo();
8812 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508813 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118814 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538815 EXPECT_FALSE(response->was_fetched_via_spdy);
8816 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118817
8818 std::string response_data;
8819 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8820 EXPECT_EQ("hello world", response_data);
8821
[email protected]90499482013-06-01 00:39:508822 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118823
[email protected]49639fa2011-12-20 23:22:418824 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118825 EXPECT_EQ(ERR_IO_PENDING, rv);
8826 EXPECT_EQ(OK, callback.WaitForResult());
8827
8828 response = trans->GetResponseInfo();
8829 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508830 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118831 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538832 EXPECT_TRUE(response->was_fetched_via_spdy);
8833 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118834
8835 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8836 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558837 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:428838 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:118839 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:428840 EXPECT_EQ("https://www.google.com/",
8841 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:118842
[email protected]029c83b62013-01-24 05:28:208843 LoadTimingInfo load_timing_info;
8844 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8845 TestLoadTimingNotReusedWithPac(load_timing_info,
8846 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:118847}
[email protected]631f1322010-04-30 17:59:118848
[email protected]23e482282013-06-14 16:08:028849TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:548850 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:388851 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038852 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548853
8854 HttpRequestInfo request;
8855 request.method = "GET";
8856 request.url = GURL("http://www.google.com/");
8857 request.load_flags = 0;
8858
[email protected]8a0fc822013-06-27 20:52:438859 std::string alternate_protocol_http_header =
8860 GetAlternateProtocolHttpHeader();
8861
[email protected]2ff8b312010-04-26 22:20:548862 MockRead data_reads[] = {
8863 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438864 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548865 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068866 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:548867 };
8868
8869 StaticSocketDataProvider first_transaction(
8870 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078871 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548872
[email protected]8ddf8322012-02-23 18:08:068873 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028874 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548876
[email protected]cdf8f7e72013-05-23 10:56:468877 scoped_ptr<SpdyFrame> req(
8878 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138879 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548880
[email protected]23e482282013-06-14 16:08:028881 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8882 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548883 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138884 CreateMockRead(*resp),
8885 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068886 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548887 };
8888
[email protected]dd54bd82012-07-19 23:44:578889 DelayedSocketData spdy_data(
8890 1, // wait for one write to finish before reading.
8891 spdy_reads, arraysize(spdy_reads),
8892 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078893 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548894
[email protected]83039bb2011-12-09 18:43:558895 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548896
[email protected]bb88e1d32013-05-03 23:11:078897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:548898
[email protected]262eec82013-03-19 21:01:368899 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548901
[email protected]49639fa2011-12-20 23:22:418902 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548903 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418904 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548905
8906 const HttpResponseInfo* response = trans->GetResponseInfo();
8907 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508908 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8910
8911 std::string response_data;
8912 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8913 EXPECT_EQ("hello world", response_data);
8914
8915 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:388916 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:408917 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
8918 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:278919 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:268920 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:388921
[email protected]90499482013-06-01 00:39:508922 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548923
[email protected]49639fa2011-12-20 23:22:418924 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548925 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418926 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548927
8928 response = trans->GetResponseInfo();
8929 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508930 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548931 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538932 EXPECT_TRUE(response->was_fetched_via_spdy);
8933 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548934
8935 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8936 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:428937}
8938
[email protected]044de0642010-06-17 10:42:158939// GenerateAuthToken is a mighty big test.
8940// It tests all permutation of GenerateAuthToken behavior:
8941// - Synchronous and Asynchronous completion.
8942// - OK or error on completion.
8943// - Direct connection, non-authenticating proxy, and authenticating proxy.
8944// - HTTP or HTTPS backend (to include proxy tunneling).
8945// - Non-authenticating and authenticating backend.
8946//
[email protected]fe3b7dc2012-02-03 19:52:098947// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:158948// problems generating an auth token for an authenticating proxy, we don't
8949// need to test all permutations of the backend server).
8950//
8951// The test proceeds by going over each of the configuration cases, and
8952// potentially running up to three rounds in each of the tests. The TestConfig
8953// specifies both the configuration for the test as well as the expectations
8954// for the results.
[email protected]23e482282013-06-14 16:08:028955TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:508956 static const char kServer[] = "http://www.example.com";
8957 static const char kSecureServer[] = "https://www.example.com";
8958 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:158959 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
8960
8961 enum AuthTiming {
8962 AUTH_NONE,
8963 AUTH_SYNC,
8964 AUTH_ASYNC,
8965 };
8966
8967 const MockWrite kGet(
8968 "GET / HTTP/1.1\r\n"
8969 "Host: www.example.com\r\n"
8970 "Connection: keep-alive\r\n\r\n");
8971 const MockWrite kGetProxy(
8972 "GET http://www.example.com/ HTTP/1.1\r\n"
8973 "Host: www.example.com\r\n"
8974 "Proxy-Connection: keep-alive\r\n\r\n");
8975 const MockWrite kGetAuth(
8976 "GET / HTTP/1.1\r\n"
8977 "Host: www.example.com\r\n"
8978 "Connection: keep-alive\r\n"
8979 "Authorization: auth_token\r\n\r\n");
8980 const MockWrite kGetProxyAuth(
8981 "GET http://www.example.com/ HTTP/1.1\r\n"
8982 "Host: www.example.com\r\n"
8983 "Proxy-Connection: keep-alive\r\n"
8984 "Proxy-Authorization: auth_token\r\n\r\n");
8985 const MockWrite kGetAuthThroughProxy(
8986 "GET http://www.example.com/ HTTP/1.1\r\n"
8987 "Host: www.example.com\r\n"
8988 "Proxy-Connection: keep-alive\r\n"
8989 "Authorization: auth_token\r\n\r\n");
8990 const MockWrite kGetAuthWithProxyAuth(
8991 "GET http://www.example.com/ HTTP/1.1\r\n"
8992 "Host: www.example.com\r\n"
8993 "Proxy-Connection: keep-alive\r\n"
8994 "Proxy-Authorization: auth_token\r\n"
8995 "Authorization: auth_token\r\n\r\n");
8996 const MockWrite kConnect(
8997 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8998 "Host: www.example.com\r\n"
8999 "Proxy-Connection: keep-alive\r\n\r\n");
9000 const MockWrite kConnectProxyAuth(
9001 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9002 "Host: www.example.com\r\n"
9003 "Proxy-Connection: keep-alive\r\n"
9004 "Proxy-Authorization: auth_token\r\n\r\n");
9005
9006 const MockRead kSuccess(
9007 "HTTP/1.1 200 OK\r\n"
9008 "Content-Type: text/html; charset=iso-8859-1\r\n"
9009 "Content-Length: 3\r\n\r\n"
9010 "Yes");
9011 const MockRead kFailure(
9012 "Should not be called.");
9013 const MockRead kServerChallenge(
9014 "HTTP/1.1 401 Unauthorized\r\n"
9015 "WWW-Authenticate: Mock realm=server\r\n"
9016 "Content-Type: text/html; charset=iso-8859-1\r\n"
9017 "Content-Length: 14\r\n\r\n"
9018 "Unauthorized\r\n");
9019 const MockRead kProxyChallenge(
9020 "HTTP/1.1 407 Unauthorized\r\n"
9021 "Proxy-Authenticate: Mock realm=proxy\r\n"
9022 "Proxy-Connection: close\r\n"
9023 "Content-Type: text/html; charset=iso-8859-1\r\n"
9024 "Content-Length: 14\r\n\r\n"
9025 "Unauthorized\r\n");
9026 const MockRead kProxyConnected(
9027 "HTTP/1.1 200 Connection Established\r\n\r\n");
9028
9029 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9030 // no constructors, but the C++ compiler on Windows warns about
9031 // unspecified data in compound literals. So, moved to using constructors,
9032 // and TestRound's created with the default constructor should not be used.
9033 struct TestRound {
9034 TestRound()
9035 : expected_rv(ERR_UNEXPECTED),
9036 extra_write(NULL),
9037 extra_read(NULL) {
9038 }
9039 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9040 int expected_rv_arg)
9041 : write(write_arg),
9042 read(read_arg),
9043 expected_rv(expected_rv_arg),
9044 extra_write(NULL),
9045 extra_read(NULL) {
9046 }
9047 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9048 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019049 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159050 : write(write_arg),
9051 read(read_arg),
9052 expected_rv(expected_rv_arg),
9053 extra_write(extra_write_arg),
9054 extra_read(extra_read_arg) {
9055 }
9056 MockWrite write;
9057 MockRead read;
9058 int expected_rv;
9059 const MockWrite* extra_write;
9060 const MockRead* extra_read;
9061 };
9062
9063 static const int kNoSSL = 500;
9064
9065 struct TestConfig {
9066 const char* proxy_url;
9067 AuthTiming proxy_auth_timing;
9068 int proxy_auth_rv;
9069 const char* server_url;
9070 AuthTiming server_auth_timing;
9071 int server_auth_rv;
9072 int num_auth_rounds;
9073 int first_ssl_round;
9074 TestRound rounds[3];
9075 } test_configs[] = {
9076 // Non-authenticating HTTP server with a direct connection.
9077 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9078 { TestRound(kGet, kSuccess, OK)}},
9079 // Authenticating HTTP server with a direct connection.
9080 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9081 { TestRound(kGet, kServerChallenge, OK),
9082 TestRound(kGetAuth, kSuccess, OK)}},
9083 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9084 { TestRound(kGet, kServerChallenge, OK),
9085 TestRound(kGetAuth, kFailure, kAuthErr)}},
9086 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9087 { TestRound(kGet, kServerChallenge, OK),
9088 TestRound(kGetAuth, kSuccess, OK)}},
9089 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9090 { TestRound(kGet, kServerChallenge, OK),
9091 TestRound(kGetAuth, kFailure, kAuthErr)}},
9092 // Non-authenticating HTTP server through a non-authenticating proxy.
9093 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9094 { TestRound(kGetProxy, kSuccess, OK)}},
9095 // Authenticating HTTP server through a non-authenticating proxy.
9096 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9097 { TestRound(kGetProxy, kServerChallenge, OK),
9098 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9099 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9100 { TestRound(kGetProxy, kServerChallenge, OK),
9101 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9102 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9103 { TestRound(kGetProxy, kServerChallenge, OK),
9104 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9105 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9106 { TestRound(kGetProxy, kServerChallenge, OK),
9107 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9108 // Non-authenticating HTTP server through an authenticating proxy.
9109 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9110 { TestRound(kGetProxy, kProxyChallenge, OK),
9111 TestRound(kGetProxyAuth, kSuccess, OK)}},
9112 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9113 { TestRound(kGetProxy, kProxyChallenge, OK),
9114 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9115 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9116 { TestRound(kGetProxy, kProxyChallenge, OK),
9117 TestRound(kGetProxyAuth, kSuccess, OK)}},
9118 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9119 { TestRound(kGetProxy, kProxyChallenge, OK),
9120 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9121 // Authenticating HTTP server through an authenticating proxy.
9122 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9123 { TestRound(kGetProxy, kProxyChallenge, OK),
9124 TestRound(kGetProxyAuth, kServerChallenge, OK),
9125 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9126 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9127 { TestRound(kGetProxy, kProxyChallenge, OK),
9128 TestRound(kGetProxyAuth, kServerChallenge, OK),
9129 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9130 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9131 { TestRound(kGetProxy, kProxyChallenge, OK),
9132 TestRound(kGetProxyAuth, kServerChallenge, OK),
9133 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9134 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9135 { TestRound(kGetProxy, kProxyChallenge, OK),
9136 TestRound(kGetProxyAuth, kServerChallenge, OK),
9137 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9138 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9139 { TestRound(kGetProxy, kProxyChallenge, OK),
9140 TestRound(kGetProxyAuth, kServerChallenge, OK),
9141 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9142 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9143 { TestRound(kGetProxy, kProxyChallenge, OK),
9144 TestRound(kGetProxyAuth, kServerChallenge, OK),
9145 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9146 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9147 { TestRound(kGetProxy, kProxyChallenge, OK),
9148 TestRound(kGetProxyAuth, kServerChallenge, OK),
9149 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9150 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9151 { TestRound(kGetProxy, kProxyChallenge, OK),
9152 TestRound(kGetProxyAuth, kServerChallenge, OK),
9153 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9154 // Non-authenticating HTTPS server with a direct connection.
9155 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9156 { TestRound(kGet, kSuccess, OK)}},
9157 // Authenticating HTTPS server with a direct connection.
9158 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9159 { TestRound(kGet, kServerChallenge, OK),
9160 TestRound(kGetAuth, kSuccess, OK)}},
9161 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9162 { TestRound(kGet, kServerChallenge, OK),
9163 TestRound(kGetAuth, kFailure, kAuthErr)}},
9164 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9165 { TestRound(kGet, kServerChallenge, OK),
9166 TestRound(kGetAuth, kSuccess, OK)}},
9167 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9168 { TestRound(kGet, kServerChallenge, OK),
9169 TestRound(kGetAuth, kFailure, kAuthErr)}},
9170 // Non-authenticating HTTPS server with a non-authenticating proxy.
9171 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9172 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9173 // Authenticating HTTPS server through a non-authenticating proxy.
9174 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9175 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9176 TestRound(kGetAuth, kSuccess, OK)}},
9177 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9178 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9179 TestRound(kGetAuth, kFailure, kAuthErr)}},
9180 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9181 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9182 TestRound(kGetAuth, kSuccess, OK)}},
9183 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9184 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9185 TestRound(kGetAuth, kFailure, kAuthErr)}},
9186 // Non-Authenticating HTTPS server through an authenticating proxy.
9187 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9188 { TestRound(kConnect, kProxyChallenge, OK),
9189 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9190 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9191 { TestRound(kConnect, kProxyChallenge, OK),
9192 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9193 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9194 { TestRound(kConnect, kProxyChallenge, OK),
9195 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9196 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9197 { TestRound(kConnect, kProxyChallenge, OK),
9198 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9199 // Authenticating HTTPS server through an authenticating proxy.
9200 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9201 { TestRound(kConnect, kProxyChallenge, OK),
9202 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9203 &kGet, &kServerChallenge),
9204 TestRound(kGetAuth, kSuccess, OK)}},
9205 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9206 { TestRound(kConnect, kProxyChallenge, OK),
9207 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9208 &kGet, &kServerChallenge),
9209 TestRound(kGetAuth, kFailure, kAuthErr)}},
9210 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9211 { TestRound(kConnect, kProxyChallenge, OK),
9212 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9213 &kGet, &kServerChallenge),
9214 TestRound(kGetAuth, kSuccess, OK)}},
9215 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9216 { TestRound(kConnect, kProxyChallenge, OK),
9217 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9218 &kGet, &kServerChallenge),
9219 TestRound(kGetAuth, kFailure, kAuthErr)}},
9220 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9221 { TestRound(kConnect, kProxyChallenge, OK),
9222 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9223 &kGet, &kServerChallenge),
9224 TestRound(kGetAuth, kSuccess, OK)}},
9225 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9226 { TestRound(kConnect, kProxyChallenge, OK),
9227 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9228 &kGet, &kServerChallenge),
9229 TestRound(kGetAuth, kFailure, kAuthErr)}},
9230 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9231 { TestRound(kConnect, kProxyChallenge, OK),
9232 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9233 &kGet, &kServerChallenge),
9234 TestRound(kGetAuth, kSuccess, OK)}},
9235 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9236 { TestRound(kConnect, kProxyChallenge, OK),
9237 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9238 &kGet, &kServerChallenge),
9239 TestRound(kGetAuth, kFailure, kAuthErr)}},
9240 };
9241
[email protected]044de0642010-06-17 10:42:159242 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089243 HttpAuthHandlerMock::Factory* auth_factory(
9244 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079245 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159246 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269247
9248 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159249 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089250 for (int n = 0; n < 2; n++) {
9251 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9252 std::string auth_challenge = "Mock realm=proxy";
9253 GURL origin(test_config.proxy_url);
9254 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9255 auth_challenge.end());
9256 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9257 origin, BoundNetLog());
9258 auth_handler->SetGenerateExpectation(
9259 test_config.proxy_auth_timing == AUTH_ASYNC,
9260 test_config.proxy_auth_rv);
9261 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9262 }
[email protected]044de0642010-06-17 10:42:159263 }
9264 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009265 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159266 std::string auth_challenge = "Mock realm=server";
9267 GURL origin(test_config.server_url);
9268 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9269 auth_challenge.end());
9270 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9271 origin, BoundNetLog());
9272 auth_handler->SetGenerateExpectation(
9273 test_config.server_auth_timing == AUTH_ASYNC,
9274 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089275 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159276 }
9277 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079278 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129279 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159280 } else {
[email protected]bb88e1d32013-05-03 23:11:079281 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159282 }
9283
9284 HttpRequestInfo request;
9285 request.method = "GET";
9286 request.url = GURL(test_config.server_url);
9287 request.load_flags = 0;
9288
[email protected]bb88e1d32013-05-03 23:11:079289 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369290 HttpNetworkTransaction trans(
[email protected]bb88e1d32013-05-03 23:11:079291 DEFAULT_PRIORITY, CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:159292
9293 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9294 const TestRound& read_write_round = test_config.rounds[round];
9295
9296 // Set up expected reads and writes.
9297 MockRead reads[2];
9298 reads[0] = read_write_round.read;
9299 size_t length_reads = 1;
9300 if (read_write_round.extra_read) {
9301 reads[1] = *read_write_round.extra_read;
9302 length_reads = 2;
9303 }
9304
9305 MockWrite writes[2];
9306 writes[0] = read_write_round.write;
9307 size_t length_writes = 1;
9308 if (read_write_round.extra_write) {
9309 writes[1] = *read_write_round.extra_write;
9310 length_writes = 2;
9311 }
9312 StaticSocketDataProvider data_provider(
9313 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079314 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159315
9316 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069317 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159318 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079319 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159320 &ssl_socket_data_provider);
9321
9322 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419323 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159324 int rv;
9325 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419326 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159327 } else {
[email protected]49639fa2011-12-20 23:22:419328 rv = trans.RestartWithAuth(
9329 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159330 }
9331 if (rv == ERR_IO_PENDING)
9332 rv = callback.WaitForResult();
9333
9334 // Compare results with expected data.
9335 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509336 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159337 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509338 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159339 } else {
9340 EXPECT_TRUE(response == NULL);
9341 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9342 continue;
9343 }
9344 if (round + 1 < test_config.num_auth_rounds) {
9345 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9346 } else {
9347 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9348 }
9349 }
[email protected]e5ae96a2010-04-14 20:12:459350 }
9351}
9352
[email protected]23e482282013-06-14 16:08:029353TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149354 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149355 HttpAuthHandlerMock::Factory* auth_factory(
9356 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079357 session_deps_.http_auth_handler_factory.reset(auth_factory);
9358 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9359 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9360 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149361
9362 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9363 auth_handler->set_connection_based(true);
9364 std::string auth_challenge = "Mock realm=server";
9365 GURL origin("http://www.example.com");
9366 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9367 auth_challenge.end());
9368 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9369 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089370 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149371
[email protected]c871bce92010-07-15 21:51:149372 int rv = OK;
9373 const HttpResponseInfo* response = NULL;
9374 HttpRequestInfo request;
9375 request.method = "GET";
9376 request.url = origin;
9377 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279378
[email protected]bb88e1d32013-05-03 23:11:079379 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109380
9381 // Use a TCP Socket Pool with only one connection per group. This is used
9382 // to validate that the TCP socket is not released to the pool between
9383 // each round of multi-round authentication.
9384 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289385 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9386 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109387 50, // Max sockets for pool
9388 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289389 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079390 session_deps_.host_resolver.get(),
9391 session_deps_.socket_factory.get(),
9392 session_deps_.net_log);
[email protected]a42dbd142011-11-17 16:42:029393 MockClientSocketPoolManager* mock_pool_manager =
9394 new MockClientSocketPoolManager;
9395 mock_pool_manager->SetTransportSocketPool(transport_pool);
9396 session_peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]7ef4cbbb2011-02-06 11:19:109397
[email protected]262eec82013-03-19 21:01:369398 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419400 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149401
9402 const MockWrite kGet(
9403 "GET / HTTP/1.1\r\n"
9404 "Host: www.example.com\r\n"
9405 "Connection: keep-alive\r\n\r\n");
9406 const MockWrite kGetAuth(
9407 "GET / HTTP/1.1\r\n"
9408 "Host: www.example.com\r\n"
9409 "Connection: keep-alive\r\n"
9410 "Authorization: auth_token\r\n\r\n");
9411
9412 const MockRead kServerChallenge(
9413 "HTTP/1.1 401 Unauthorized\r\n"
9414 "WWW-Authenticate: Mock realm=server\r\n"
9415 "Content-Type: text/html; charset=iso-8859-1\r\n"
9416 "Content-Length: 14\r\n\r\n"
9417 "Unauthorized\r\n");
9418 const MockRead kSuccess(
9419 "HTTP/1.1 200 OK\r\n"
9420 "Content-Type: text/html; charset=iso-8859-1\r\n"
9421 "Content-Length: 3\r\n\r\n"
9422 "Yes");
9423
9424 MockWrite writes[] = {
9425 // First round
9426 kGet,
9427 // Second round
9428 kGetAuth,
9429 // Third round
9430 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309431 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109432 kGetAuth,
9433 // Competing request
9434 kGet,
[email protected]c871bce92010-07-15 21:51:149435 };
9436 MockRead reads[] = {
9437 // First round
9438 kServerChallenge,
9439 // Second round
9440 kServerChallenge,
9441 // Third round
[email protected]eca50e122010-09-11 14:03:309442 kServerChallenge,
9443 // Fourth round
[email protected]c871bce92010-07-15 21:51:149444 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109445 // Competing response
9446 kSuccess,
[email protected]c871bce92010-07-15 21:51:149447 };
9448 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9449 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079450 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149451
[email protected]7ef4cbbb2011-02-06 11:19:109452 const char* const kSocketGroup = "www.example.com:80";
9453
9454 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149455 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419456 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149457 if (rv == ERR_IO_PENDING)
9458 rv = callback.WaitForResult();
9459 EXPECT_EQ(OK, rv);
9460 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509461 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149462 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289463 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149464
[email protected]7ef4cbbb2011-02-06 11:19:109465 // In between rounds, another request comes in for the same domain.
9466 // It should not be able to grab the TCP socket that trans has already
9467 // claimed.
9468 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509469 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419470 TestCompletionCallback callback_compete;
9471 rv = trans_compete->Start(
9472 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109473 EXPECT_EQ(ERR_IO_PENDING, rv);
9474 // callback_compete.WaitForResult at this point would stall forever,
9475 // since the HttpNetworkTransaction does not release the request back to
9476 // the pool until after authentication completes.
9477
9478 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149479 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419480 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149481 if (rv == ERR_IO_PENDING)
9482 rv = callback.WaitForResult();
9483 EXPECT_EQ(OK, rv);
9484 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509485 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149486 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289487 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149488
[email protected]7ef4cbbb2011-02-06 11:19:109489 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149490 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419491 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149492 if (rv == ERR_IO_PENDING)
9493 rv = callback.WaitForResult();
9494 EXPECT_EQ(OK, rv);
9495 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509496 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149497 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289498 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309499
[email protected]7ef4cbbb2011-02-06 11:19:109500 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309501 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419502 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309503 if (rv == ERR_IO_PENDING)
9504 rv = callback.WaitForResult();
9505 EXPECT_EQ(OK, rv);
9506 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509507 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309508 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289509 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109510
9511 // Read the body since the fourth round was successful. This will also
9512 // release the socket back to the pool.
9513 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509514 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109515 if (rv == ERR_IO_PENDING)
9516 rv = callback.WaitForResult();
9517 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509518 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109519 EXPECT_EQ(0, rv);
9520 // There are still 0 idle sockets, since the trans_compete transaction
9521 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289522 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109523
9524 // The competing request can now finish. Wait for the headers and then
9525 // read the body.
9526 rv = callback_compete.WaitForResult();
9527 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509528 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109529 if (rv == ERR_IO_PENDING)
9530 rv = callback.WaitForResult();
9531 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509532 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109533 EXPECT_EQ(0, rv);
9534
9535 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289536 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149537}
9538
[email protected]65041fa2010-05-21 06:56:539539// This tests the case that a request is issued via http instead of spdy after
9540// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029541TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389542 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169543 std::vector<NextProto> next_protos;
9544 next_protos.push_back(kProtoHTTP11);
9545 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539546 HttpRequestInfo request;
9547 request.method = "GET";
9548 request.url = GURL("https://www.google.com/");
9549 request.load_flags = 0;
9550
9551 MockWrite data_writes[] = {
9552 MockWrite("GET / HTTP/1.1\r\n"
9553 "Host: www.google.com\r\n"
9554 "Connection: keep-alive\r\n\r\n"),
9555 };
9556
[email protected]8a0fc822013-06-27 20:52:439557 std::string alternate_protocol_http_header =
9558 GetAlternateProtocolHttpHeader();
9559
[email protected]65041fa2010-05-21 06:56:539560 MockRead data_reads[] = {
9561 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439562 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539563 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069564 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539565 };
9566
[email protected]8ddf8322012-02-23 18:08:069567 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539568 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9569 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469570 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539571
[email protected]bb88e1d32013-05-03 23:11:079572 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539573
9574 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9575 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079576 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539577
[email protected]49639fa2011-12-20 23:22:419578 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539579
[email protected]bb88e1d32013-05-03 23:11:079580 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369581 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539583
[email protected]49639fa2011-12-20 23:22:419584 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539585
9586 EXPECT_EQ(ERR_IO_PENDING, rv);
9587 EXPECT_EQ(OK, callback.WaitForResult());
9588
9589 const HttpResponseInfo* response = trans->GetResponseInfo();
9590 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509591 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539592 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9593
9594 std::string response_data;
9595 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9596 EXPECT_EQ("hello world", response_data);
9597
9598 EXPECT_FALSE(response->was_fetched_via_spdy);
9599 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539600}
[email protected]26ef6582010-06-24 02:30:479601
[email protected]23e482282013-06-14 16:08:029602TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479603 // Simulate the SSL handshake completing with an NPN negotiation
9604 // followed by an immediate server closing of the socket.
9605 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389606 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039607 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479608
9609 HttpRequestInfo request;
9610 request.method = "GET";
9611 request.url = GURL("https://www.google.com/");
9612 request.load_flags = 0;
9613
[email protected]8ddf8322012-02-23 18:08:069614 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029615 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479617
[email protected]cdf8f7e72013-05-23 10:56:469618 scoped_ptr<SpdyFrame> req(
9619 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139620 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479621
9622 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069623 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479624 };
9625
[email protected]dd54bd82012-07-19 23:44:579626 DelayedSocketData spdy_data(
9627 0, // don't wait in this case, immediate hangup.
9628 spdy_reads, arraysize(spdy_reads),
9629 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079630 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479631
[email protected]49639fa2011-12-20 23:22:419632 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479633
[email protected]bb88e1d32013-05-03 23:11:079634 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369635 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479637
[email protected]49639fa2011-12-20 23:22:419638 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479639 EXPECT_EQ(ERR_IO_PENDING, rv);
9640 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479641}
[email protected]65d34382010-07-01 18:12:269642
[email protected]795cbf82013-07-22 09:37:279643// A subclass of HttpAuthHandlerMock that records the request URL when
9644// it gets it. This is needed since the auth handler may get destroyed
9645// before we get a chance to query it.
9646class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9647 public:
9648 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9649
9650 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9651
9652 protected:
9653 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9654 const HttpRequestInfo* request,
9655 const CompletionCallback& callback,
9656 std::string* auth_token) OVERRIDE {
9657 *url_ = request->url;
9658 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9659 credentials, request, callback, auth_token);
9660 }
9661
9662 private:
9663 GURL* url_;
9664};
9665
[email protected]23e482282013-06-14 16:08:029666TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309667 // This test ensures that the URL passed into the proxy is upgraded
9668 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389669 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439670 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309671
[email protected]bb88e1d32013-05-03 23:11:079672 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209673 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9674 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079675 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279676 GURL request_url;
9677 {
9678 HttpAuthHandlerMock::Factory* auth_factory =
9679 new HttpAuthHandlerMock::Factory();
9680 UrlRecordingHttpAuthHandlerMock* auth_handler =
9681 new UrlRecordingHttpAuthHandlerMock(&request_url);
9682 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9683 auth_factory->set_do_init_from_challenge(true);
9684 session_deps_.http_auth_handler_factory.reset(auth_factory);
9685 }
[email protected]f45c1ee2010-08-03 00:54:309686
9687 HttpRequestInfo request;
9688 request.method = "GET";
9689 request.url = GURL("http://www.google.com");
9690 request.load_flags = 0;
9691
9692 // First round goes unauthenticated through the proxy.
9693 MockWrite data_writes_1[] = {
9694 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9695 "Host: www.google.com\r\n"
9696 "Proxy-Connection: keep-alive\r\n"
9697 "\r\n"),
9698 };
9699 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069700 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309701 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239702 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309703 "Proxy-Connection: close\r\n"
9704 "\r\n"),
9705 };
9706 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9707 data_writes_1, arraysize(data_writes_1));
9708
9709 // Second round tries to tunnel to www.google.com due to the
9710 // Alternate-Protocol announcement in the first round. It fails due
9711 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599712 // After the failure, a tunnel is established to www.google.com using
9713 // Proxy-Authorization headers. There is then a SPDY request round.
9714 //
[email protected]fe3b7dc2012-02-03 19:52:099715 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9716 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9717 // does a Disconnect and Connect on the same socket, rather than trying
9718 // to obtain a new one.
9719 //
[email protected]394816e92010-08-03 07:38:599720 // NOTE: Originally, the proxy response to the second CONNECT request
9721 // simply returned another 407 so the unit test could skip the SSL connection
9722 // establishment and SPDY framing issues. Alas, the
9723 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309724 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599725
[email protected]cdf8f7e72013-05-23 10:56:469726 scoped_ptr<SpdyFrame> req(
9727 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029728 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9729 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309730
[email protected]394816e92010-08-03 07:38:599731 MockWrite data_writes_2[] = {
9732 // First connection attempt without Proxy-Authorization.
9733 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9734 "Host: www.google.com\r\n"
9735 "Proxy-Connection: keep-alive\r\n"
9736 "\r\n"),
9737
9738 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309739 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9740 "Host: www.google.com\r\n"
9741 "Proxy-Connection: keep-alive\r\n"
9742 "Proxy-Authorization: auth_token\r\n"
9743 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309744
[email protected]394816e92010-08-03 07:38:599745 // SPDY request
9746 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309747 };
[email protected]394816e92010-08-03 07:38:599748 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9749 "Proxy-Authenticate: Mock\r\n"
9750 "Proxy-Connection: close\r\n"
9751 "\r\n");
9752 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9753 MockRead data_reads_2[] = {
9754 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069755 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9756 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599757 arraysize(kRejectConnectResponse) - 1, 1),
9758
9759 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069760 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:099761 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:599762
9763 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:099764 CreateMockRead(*resp.get(), 6),
9765 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:069766 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:599767 };
[email protected]dd54bd82012-07-19 23:44:579768 OrderedSocketData data_2(
9769 data_reads_2, arraysize(data_reads_2),
9770 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:309771
[email protected]8ddf8322012-02-23 18:08:069772 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029773 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:309774
[email protected]d973e99a2012-02-17 21:02:369775 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559776 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9777 NULL, 0, NULL, 0);
9778 hanging_non_alternate_protocol_socket.set_connect_data(
9779 never_finishing_connect);
9780
[email protected]bb88e1d32013-05-03 23:11:079781 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9782 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9784 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559785 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:079786 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:309787
9788 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:419789 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:369790 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:509791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419792 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309793 EXPECT_EQ(ERR_IO_PENDING, rv);
9794 EXPECT_EQ(OK, callback_1.WaitForResult());
9795
9796 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:419797 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:369798 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:509799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419800 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309801 EXPECT_EQ(ERR_IO_PENDING, rv);
9802 EXPECT_EQ(OK, callback_2.WaitForResult());
9803 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509804 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:309805 ASSERT_FALSE(response->auth_challenge.get() == NULL);
9806
9807 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:419808 TestCompletionCallback callback_3;
9809 rv = trans_2->RestartWithAuth(
9810 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:309811 EXPECT_EQ(ERR_IO_PENDING, rv);
9812 EXPECT_EQ(OK, callback_3.WaitForResult());
9813
9814 // After all that work, these two lines (or actually, just the scheme) are
9815 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:309816 EXPECT_EQ("https", request_url.scheme());
9817 EXPECT_EQ("www.google.com", request_url.host());
9818
[email protected]029c83b62013-01-24 05:28:209819 LoadTimingInfo load_timing_info;
9820 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9821 TestLoadTimingNotReusedWithPac(load_timing_info,
9822 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:389823}
9824
9825// Test that if we cancel the transaction as the connection is completing, that
9826// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:029827TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:389828 // Setup everything about the connection to complete synchronously, so that
9829 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9830 // for is the callback from the HttpStreamRequest.
9831 // Then cancel the transaction.
9832 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:369833 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:389834 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069835 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9836 MockRead(SYNCHRONOUS, "hello world"),
9837 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:389838 };
9839
[email protected]8e6441ca2010-08-19 05:56:389840 HttpRequestInfo request;
9841 request.method = "GET";
9842 request.url = GURL("http://www.google.com/");
9843 request.load_flags = 0;
9844
[email protected]bb88e1d32013-05-03 23:11:079845 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]cb9bf6ca2011-01-28 13:15:279846 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:369847 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:079848 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:279849
[email protected]8e6441ca2010-08-19 05:56:389850 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9851 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079852 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:389853
[email protected]49639fa2011-12-20 23:22:419854 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:389855
[email protected]333bdf62012-06-08 22:57:299856 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:419857 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:389858 EXPECT_EQ(ERR_IO_PENDING, rv);
9859 trans.reset(); // Cancel the transaction here.
9860
[email protected]2da659e2013-05-23 20:51:349861 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:309862}
9863
[email protected]76a505b2010-08-25 06:23:009864// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029865TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:079866 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209867 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299868 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079869 session_deps_.net_log = log.bound().net_log();
9870 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009871
[email protected]76a505b2010-08-25 06:23:009872 HttpRequestInfo request;
9873 request.method = "GET";
9874 request.url = GURL("http://www.google.com/");
9875
9876 MockWrite data_writes1[] = {
9877 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9878 "Host: www.google.com\r\n"
9879 "Proxy-Connection: keep-alive\r\n\r\n"),
9880 };
9881
9882 MockRead data_reads1[] = {
9883 MockRead("HTTP/1.1 200 OK\r\n"),
9884 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9885 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069886 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009887 };
9888
9889 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9890 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079891 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:009892
[email protected]49639fa2011-12-20 23:22:419893 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009894
[email protected]262eec82013-03-19 21:01:369895 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509897
[email protected]49639fa2011-12-20 23:22:419898 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009899 EXPECT_EQ(ERR_IO_PENDING, rv);
9900
9901 rv = callback1.WaitForResult();
9902 EXPECT_EQ(OK, rv);
9903
9904 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509905 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009906
9907 EXPECT_TRUE(response->headers->IsKeepAlive());
9908 EXPECT_EQ(200, response->headers->response_code());
9909 EXPECT_EQ(100, response->headers->GetContentLength());
9910 EXPECT_TRUE(response->was_fetched_via_proxy);
9911 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209912
9913 LoadTimingInfo load_timing_info;
9914 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9915 TestLoadTimingNotReusedWithPac(load_timing_info,
9916 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:009917}
9918
9919// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029920TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:079921 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209922 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299923 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079924 session_deps_.net_log = log.bound().net_log();
9925 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009926
[email protected]76a505b2010-08-25 06:23:009927 HttpRequestInfo request;
9928 request.method = "GET";
9929 request.url = GURL("https://www.google.com/");
9930
9931 // Since we have proxy, should try to establish tunnel.
9932 MockWrite data_writes1[] = {
9933 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9934 "Host: www.google.com\r\n"
9935 "Proxy-Connection: keep-alive\r\n\r\n"),
9936
9937 MockWrite("GET / HTTP/1.1\r\n"
9938 "Host: www.google.com\r\n"
9939 "Connection: keep-alive\r\n\r\n"),
9940 };
9941
9942 MockRead data_reads1[] = {
9943 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
9944
9945 MockRead("HTTP/1.1 200 OK\r\n"),
9946 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9947 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069948 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009949 };
9950
9951 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9952 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079953 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069954 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009956
[email protected]49639fa2011-12-20 23:22:419957 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009958
[email protected]262eec82013-03-19 21:01:369959 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509960 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509961
[email protected]49639fa2011-12-20 23:22:419962 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009963 EXPECT_EQ(ERR_IO_PENDING, rv);
9964
9965 rv = callback1.WaitForResult();
9966 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:579967 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409968 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009969 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409970 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009971 NetLog::PHASE_NONE);
9972 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409973 entries, pos,
[email protected]76a505b2010-08-25 06:23:009974 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9975 NetLog::PHASE_NONE);
9976
9977 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509978 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009979
9980 EXPECT_TRUE(response->headers->IsKeepAlive());
9981 EXPECT_EQ(200, response->headers->response_code());
9982 EXPECT_EQ(100, response->headers->GetContentLength());
9983 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9984 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:209985
9986 LoadTimingInfo load_timing_info;
9987 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9988 TestLoadTimingNotReusedWithPac(load_timing_info,
9989 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:009990}
9991
9992// Test a basic HTTPS GET request through a proxy, but the server hangs up
9993// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:029994TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:079995 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299996 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079997 session_deps_.net_log = log.bound().net_log();
9998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009999
[email protected]76a505b2010-08-25 06:23:0010000 HttpRequestInfo request;
10001 request.method = "GET";
10002 request.url = GURL("https://www.google.com/");
10003
10004 // Since we have proxy, should try to establish tunnel.
10005 MockWrite data_writes1[] = {
10006 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10007 "Host: www.google.com\r\n"
10008 "Proxy-Connection: keep-alive\r\n\r\n"),
10009
10010 MockWrite("GET / HTTP/1.1\r\n"
10011 "Host: www.google.com\r\n"
10012 "Connection: keep-alive\r\n\r\n"),
10013 };
10014
10015 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610016 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010017 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610018 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010019 };
10020
10021 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10022 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710023 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610024 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710025 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010026
[email protected]49639fa2011-12-20 23:22:4110027 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010028
[email protected]262eec82013-03-19 21:01:3610029 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010031
[email protected]49639fa2011-12-20 23:22:4110032 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010033 EXPECT_EQ(ERR_IO_PENDING, rv);
10034
10035 rv = callback1.WaitForResult();
10036 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710037 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010038 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010039 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010040 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010041 NetLog::PHASE_NONE);
10042 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010043 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010044 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10045 NetLog::PHASE_NONE);
10046}
10047
[email protected]749eefa82010-09-13 22:14:0310048// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210049TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610050 scoped_ptr<SpdyFrame> req(
10051 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310052 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10053
[email protected]23e482282013-06-14 16:08:0210054 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10055 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310056 MockRead spdy_reads[] = {
10057 CreateMockRead(*resp),
10058 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610059 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310060 };
10061
[email protected]dd54bd82012-07-19 23:44:5710062 DelayedSocketData spdy_data(
10063 1, // wait for one write to finish before reading.
10064 spdy_reads, arraysize(spdy_reads),
10065 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710066 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310067
[email protected]8ddf8322012-02-23 18:08:0610068 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210069 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710070 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310071
[email protected]bb88e1d32013-05-03 23:11:0710072 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310073
10074 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810075 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010076 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10077 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:2710078 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610079 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310080
10081 HttpRequestInfo request;
10082 request.method = "GET";
10083 request.url = GURL("https://www.google.com/");
10084 request.load_flags = 0;
10085
10086 // This is the important line that marks this as a preconnect.
10087 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10088
[email protected]262eec82013-03-19 21:01:3610089 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310091
[email protected]41d64e82013-07-03 22:44:2610092 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110093 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310094 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110095 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310096}
10097
[email protected]73b8dd222010-11-11 19:55:2410098// Given a net error, cause that error to be returned from the first Write()
10099// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210100void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710101 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710102 net::HttpRequestInfo request_info;
10103 request_info.url = GURL("https://www.example.com/");
10104 request_info.method = "GET";
10105 request_info.load_flags = net::LOAD_NORMAL;
10106
[email protected]8ddf8322012-02-23 18:08:0610107 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410108 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610109 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410110 };
10111 net::StaticSocketDataProvider data(NULL, 0,
10112 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710113 session_deps_.socket_factory->AddSocketDataProvider(&data);
10114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410115
[email protected]bb88e1d32013-05-03 23:11:0710116 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610117 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410119
[email protected]49639fa2011-12-20 23:22:4110120 TestCompletionCallback callback;
10121 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410122 if (rv == net::ERR_IO_PENDING)
10123 rv = callback.WaitForResult();
10124 ASSERT_EQ(error, rv);
10125}
10126
[email protected]23e482282013-06-14 16:08:0210127TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410128 // Just check a grab bag of cert errors.
10129 static const int kErrors[] = {
10130 ERR_CERT_COMMON_NAME_INVALID,
10131 ERR_CERT_AUTHORITY_INVALID,
10132 ERR_CERT_DATE_INVALID,
10133 };
10134 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610135 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10136 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410137 }
10138}
10139
[email protected]bd0b6772011-01-11 19:59:3010140// Ensure that a client certificate is removed from the SSL client auth
10141// cache when:
10142// 1) No proxy is involved.
10143// 2) TLS False Start is disabled.
10144// 3) The initial TLS handshake requests a client certificate.
10145// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210146TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310147 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710148 net::HttpRequestInfo request_info;
10149 request_info.url = GURL("https://www.example.com/");
10150 request_info.method = "GET";
10151 request_info.load_flags = net::LOAD_NORMAL;
10152
[email protected]bd0b6772011-01-11 19:59:3010153 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10154 cert_request->host_and_port = "www.example.com:443";
10155
10156 // [ssl_]data1 contains the data for the first SSL handshake. When a
10157 // CertificateRequest is received for the first time, the handshake will
10158 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610159 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010160 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010162 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710163 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010164
10165 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10166 // False Start is not being used, the result of the SSL handshake will be
10167 // returned as part of the SSLClientSocket::Connect() call. This test
10168 // matches the result of a server sending a handshake_failure alert,
10169 // rather than a Finished message, because it requires a client
10170 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610171 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010172 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710173 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010174 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710175 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010176
10177 // [ssl_]data3 contains the data for the third SSL handshake. When a
10178 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710179 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10180 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010181 // of the HttpNetworkTransaction. Because this test failure is due to
10182 // requiring a client certificate, this fallback handshake should also
10183 // fail.
[email protected]8ddf8322012-02-23 18:08:0610184 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010185 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010187 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710188 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010189
[email protected]80c75f682012-05-26 16:22:1710190 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10191 // connection to a server fails during an SSL handshake,
10192 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10193 // connection was attempted with TLSv1. This is transparent to the caller
10194 // of the HttpNetworkTransaction. Because this test failure is due to
10195 // requiring a client certificate, this fallback handshake should also
10196 // fail.
10197 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10198 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710200 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710201 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710202
[email protected]7799de12013-05-30 05:52:5110203 // Need one more if TLSv1.2 is enabled.
10204 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10205 ssl_data5.cert_request_info = cert_request.get();
10206 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10207 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10208 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10209
[email protected]bb88e1d32013-05-03 23:11:0710210 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610211 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010213
[email protected]bd0b6772011-01-11 19:59:3010214 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110215 TestCompletionCallback callback;
10216 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010217 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10218
10219 // Complete the SSL handshake, which should abort due to requiring a
10220 // client certificate.
10221 rv = callback.WaitForResult();
10222 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10223
10224 // Indicate that no certificate should be supplied. From the perspective
10225 // of SSLClientCertCache, NULL is just as meaningful as a real
10226 // certificate, so this is the same as supply a
10227 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110228 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010229 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10230
10231 // Ensure the certificate was added to the client auth cache before
10232 // allowing the connection to continue restarting.
10233 scoped_refptr<X509Certificate> client_cert;
10234 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10235 &client_cert));
10236 ASSERT_EQ(NULL, client_cert.get());
10237
10238 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710239 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10240 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010241 rv = callback.WaitForResult();
10242 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10243
10244 // Ensure that the client certificate is removed from the cache on a
10245 // handshake failure.
10246 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10247 &client_cert));
10248}
10249
10250// Ensure that a client certificate is removed from the SSL client auth
10251// cache when:
10252// 1) No proxy is involved.
10253// 2) TLS False Start is enabled.
10254// 3) The initial TLS handshake requests a client certificate.
10255// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210256TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310257 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710258 net::HttpRequestInfo request_info;
10259 request_info.url = GURL("https://www.example.com/");
10260 request_info.method = "GET";
10261 request_info.load_flags = net::LOAD_NORMAL;
10262
[email protected]bd0b6772011-01-11 19:59:3010263 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10264 cert_request->host_and_port = "www.example.com:443";
10265
10266 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10267 // return successfully after reading up to the peer's Certificate message.
10268 // This is to allow the caller to call SSLClientSocket::Write(), which can
10269 // enqueue application data to be sent in the same packet as the
10270 // ChangeCipherSpec and Finished messages.
10271 // The actual handshake will be finished when SSLClientSocket::Read() is
10272 // called, which expects to process the peer's ChangeCipherSpec and
10273 // Finished messages. If there was an error negotiating with the peer,
10274 // such as due to the peer requiring a client certificate when none was
10275 // supplied, the alert sent by the peer won't be processed until Read() is
10276 // called.
10277
10278 // Like the non-False Start case, when a client certificate is requested by
10279 // the peer, the handshake is aborted during the Connect() call.
10280 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610281 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010282 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710283 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010284 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710285 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010286
10287 // When a client certificate is supplied, Connect() will not be aborted
10288 // when the peer requests the certificate. Instead, the handshake will
10289 // artificially succeed, allowing the caller to write the HTTP request to
10290 // the socket. The handshake messages are not processed until Read() is
10291 // called, which then detects that the handshake was aborted, due to the
10292 // peer sending a handshake_failure because it requires a client
10293 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610294 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010295 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010297 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610298 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010299 };
10300 net::StaticSocketDataProvider data2(
10301 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710302 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010303
10304 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710305 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10306 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610307 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010308 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010310 net::StaticSocketDataProvider data3(
10311 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710312 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010313
[email protected]80c75f682012-05-26 16:22:1710314 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10315 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10316 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10317 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710319 net::StaticSocketDataProvider data4(
10320 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710321 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710322
[email protected]7799de12013-05-30 05:52:5110323 // Need one more if TLSv1.2 is enabled.
10324 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10325 ssl_data5.cert_request_info = cert_request.get();
10326 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10327 net::StaticSocketDataProvider data5(
10328 data2_reads, arraysize(data2_reads), NULL, 0);
10329 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10330
[email protected]bb88e1d32013-05-03 23:11:0710331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610332 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010334
[email protected]bd0b6772011-01-11 19:59:3010335 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110336 TestCompletionCallback callback;
10337 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010338 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10339
10340 // Complete the SSL handshake, which should abort due to requiring a
10341 // client certificate.
10342 rv = callback.WaitForResult();
10343 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10344
10345 // Indicate that no certificate should be supplied. From the perspective
10346 // of SSLClientCertCache, NULL is just as meaningful as a real
10347 // certificate, so this is the same as supply a
10348 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110349 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010350 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10351
10352 // Ensure the certificate was added to the client auth cache before
10353 // allowing the connection to continue restarting.
10354 scoped_refptr<X509Certificate> client_cert;
10355 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10356 &client_cert));
10357 ASSERT_EQ(NULL, client_cert.get());
10358
[email protected]bd0b6772011-01-11 19:59:3010359 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710360 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10361 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010362 rv = callback.WaitForResult();
10363 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10364
10365 // Ensure that the client certificate is removed from the cache on a
10366 // handshake failure.
10367 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10368 &client_cert));
10369}
10370
[email protected]8c405132011-01-11 22:03:1810371// Ensure that a client certificate is removed from the SSL client auth
10372// cache when:
10373// 1) An HTTPS proxy is involved.
10374// 3) The HTTPS proxy requests a client certificate.
10375// 4) The client supplies an invalid/unacceptable certificate for the
10376// proxy.
10377// The test is repeated twice, first for connecting to an HTTPS endpoint,
10378// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210379TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710380 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810381 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910382 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710383 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810384
10385 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10386 cert_request->host_and_port = "proxy:70";
10387
10388 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10389 // [ssl_]data[1-3]. Rather than represending the endpoint
10390 // (www.example.com:443), they represent failures with the HTTPS proxy
10391 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610392 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810393 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710394 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810395 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710396 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810397
[email protected]8ddf8322012-02-23 18:08:0610398 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810399 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710400 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810401 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710402 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810403
[email protected]80c75f682012-05-26 16:22:1710404 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10405#if 0
[email protected]8ddf8322012-02-23 18:08:0610406 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810407 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810409 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710410 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710411#endif
[email protected]8c405132011-01-11 22:03:1810412
10413 net::HttpRequestInfo requests[2];
10414 requests[0].url = GURL("https://www.example.com/");
10415 requests[0].method = "GET";
10416 requests[0].load_flags = net::LOAD_NORMAL;
10417
10418 requests[1].url = GURL("http://www.example.com/");
10419 requests[1].method = "GET";
10420 requests[1].load_flags = net::LOAD_NORMAL;
10421
10422 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710423 session_deps_.socket_factory->ResetNextMockIndexes();
10424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810425 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810427
10428 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110429 TestCompletionCallback callback;
10430 int rv = trans->Start(
10431 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810432 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10433
10434 // Complete the SSL handshake, which should abort due to requiring a
10435 // client certificate.
10436 rv = callback.WaitForResult();
10437 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10438
10439 // Indicate that no certificate should be supplied. From the perspective
10440 // of SSLClientCertCache, NULL is just as meaningful as a real
10441 // certificate, so this is the same as supply a
10442 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110443 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810444 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10445
10446 // Ensure the certificate was added to the client auth cache before
10447 // allowing the connection to continue restarting.
10448 scoped_refptr<X509Certificate> client_cert;
10449 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10450 &client_cert));
10451 ASSERT_EQ(NULL, client_cert.get());
10452 // Ensure the certificate was NOT cached for the endpoint. This only
10453 // applies to HTTPS requests, but is fine to check for HTTP requests.
10454 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10455 &client_cert));
10456
10457 // Restart the handshake. This will consume ssl_data2, which fails, and
10458 // then consume ssl_data3, which should also fail. The result code is
10459 // checked against what ssl_data3 should return.
10460 rv = callback.WaitForResult();
10461 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10462
10463 // Now that the new handshake has failed, ensure that the client
10464 // certificate was removed from the client auth cache.
10465 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10466 &client_cert));
10467 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10468 &client_cert));
10469 }
10470}
10471
[email protected]23e482282013-06-14 16:08:0210472// Unlike TEST/TEST_F, which are macros that expand to further macros,
10473// TEST_P is a macro that expands directly to code that stringizes the
10474// arguments. As a result, macros passed as parameters (such as prefix
10475// or test_case_name) will not be expanded by the preprocessor. To
10476// work around this, indirect the macro for TEST_P, so that the
10477// pre-processor will expand macros such as MAYBE_test_name before
10478// instantiating the test.
10479#define WRAPPED_TEST_P(test_case_name, test_name) \
10480 TEST_P(test_case_name, test_name)
10481
[email protected]45b170822012-05-04 21:18:1410482// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10483#if defined(OS_WIN)
10484#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10485#else
10486#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10487#endif
[email protected]23e482282013-06-14 16:08:0210488WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610489 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310490 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610491
10492 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710493 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10494 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610495 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10496 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610497
[email protected]8ddf8322012-02-23 18:08:0610498 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210499 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610501
[email protected]cdf8f7e72013-05-23 10:56:4610502 scoped_ptr<SpdyFrame> host1_req(
10503 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10504 scoped_ptr<SpdyFrame> host2_req(
10505 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610506 MockWrite spdy_writes[] = {
10507 CreateMockWrite(*host1_req, 1),
10508 CreateMockWrite(*host2_req, 4),
10509 };
[email protected]23e482282013-06-14 16:08:0210510 scoped_ptr<SpdyFrame> host1_resp(
10511 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10512 scoped_ptr<SpdyFrame> host1_resp_body(
10513 spdy_util_.ConstructSpdyBodyFrame(1, true));
10514 scoped_ptr<SpdyFrame> host2_resp(
10515 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10516 scoped_ptr<SpdyFrame> host2_resp_body(
10517 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610518 MockRead spdy_reads[] = {
10519 CreateMockRead(*host1_resp, 2),
10520 CreateMockRead(*host1_resp_body, 3),
10521 CreateMockRead(*host2_resp, 5),
10522 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610523 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610524 };
10525
[email protected]d2b5f092012-06-08 23:55:0210526 IPAddressNumber ip;
10527 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10528 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10529 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710530 OrderedSocketData spdy_data(
10531 connect,
10532 spdy_reads, arraysize(spdy_reads),
10533 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710534 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610535
[email protected]aa22b242011-11-16 18:58:2910536 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610537 HttpRequestInfo request1;
10538 request1.method = "GET";
10539 request1.url = GURL("https://www.google.com/");
10540 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010541 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610542
[email protected]49639fa2011-12-20 23:22:4110543 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610544 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110545 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610546
10547 const HttpResponseInfo* response = trans1.GetResponseInfo();
10548 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010549 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610550 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10551
10552 std::string response_data;
10553 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10554 EXPECT_EQ("hello!", response_data);
10555
10556 // Preload www.gmail.com into HostCache.
10557 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010558 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610559 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010560 rv = session_deps_.host_resolver->Resolve(resolve_info,
10561 DEFAULT_PRIORITY,
10562 &ignored,
10563 callback.callback(),
10564 NULL,
10565 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710566 EXPECT_EQ(ERR_IO_PENDING, rv);
10567 rv = callback.WaitForResult();
10568 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610569
10570 HttpRequestInfo request2;
10571 request2.method = "GET";
10572 request2.url = GURL("https://www.gmail.com/");
10573 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010574 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610575
[email protected]49639fa2011-12-20 23:22:4110576 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610577 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110578 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610579
10580 response = trans2.GetResponseInfo();
10581 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010582 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610583 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10584 EXPECT_TRUE(response->was_fetched_via_spdy);
10585 EXPECT_TRUE(response->was_npn_negotiated);
10586 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10587 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610588}
[email protected]45b170822012-05-04 21:18:1410589#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610590
[email protected]23e482282013-06-14 16:08:0210591TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210592 HttpStreamFactory::set_use_alternate_protocols(true);
10593 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10594
10595 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710596 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10597 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210598 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10599 pool_peer.DisableDomainAuthenticationVerification();
10600
10601 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210602 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210604
[email protected]cdf8f7e72013-05-23 10:56:4610605 scoped_ptr<SpdyFrame> host1_req(
10606 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10607 scoped_ptr<SpdyFrame> host2_req(
10608 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210609 MockWrite spdy_writes[] = {
10610 CreateMockWrite(*host1_req, 1),
10611 CreateMockWrite(*host2_req, 4),
10612 };
[email protected]23e482282013-06-14 16:08:0210613 scoped_ptr<SpdyFrame> host1_resp(
10614 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10615 scoped_ptr<SpdyFrame> host1_resp_body(
10616 spdy_util_.ConstructSpdyBodyFrame(1, true));
10617 scoped_ptr<SpdyFrame> host2_resp(
10618 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10619 scoped_ptr<SpdyFrame> host2_resp_body(
10620 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210621 MockRead spdy_reads[] = {
10622 CreateMockRead(*host1_resp, 2),
10623 CreateMockRead(*host1_resp_body, 3),
10624 CreateMockRead(*host2_resp, 5),
10625 CreateMockRead(*host2_resp_body, 6),
10626 MockRead(ASYNC, 0, 7),
10627 };
10628
10629 IPAddressNumber ip;
10630 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10631 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10632 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710633 OrderedSocketData spdy_data(
10634 connect,
10635 spdy_reads, arraysize(spdy_reads),
10636 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710637 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210638
10639 TestCompletionCallback callback;
10640 HttpRequestInfo request1;
10641 request1.method = "GET";
10642 request1.url = GURL("https://www.google.com/");
10643 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010644 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210645
10646 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10647 EXPECT_EQ(ERR_IO_PENDING, rv);
10648 EXPECT_EQ(OK, callback.WaitForResult());
10649
10650 const HttpResponseInfo* response = trans1.GetResponseInfo();
10651 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010652 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210653 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10654
10655 std::string response_data;
10656 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10657 EXPECT_EQ("hello!", response_data);
10658
10659 HttpRequestInfo request2;
10660 request2.method = "GET";
10661 request2.url = GURL("https://www.gmail.com/");
10662 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010663 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210664
10665 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10666 EXPECT_EQ(ERR_IO_PENDING, rv);
10667 EXPECT_EQ(OK, callback.WaitForResult());
10668
10669 response = trans2.GetResponseInfo();
10670 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010671 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210672 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10673 EXPECT_TRUE(response->was_fetched_via_spdy);
10674 EXPECT_TRUE(response->was_npn_negotiated);
10675 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10676 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210677}
10678
[email protected]e3ceb682011-06-28 23:55:4610679class OneTimeCachingHostResolver : public net::HostResolver {
10680 public:
10681 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10682 : host_port_(host_port) {}
10683 virtual ~OneTimeCachingHostResolver() {}
10684
10685 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10686
10687 // HostResolver methods:
10688 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010689 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610690 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910691 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610692 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010693 const BoundNetLog& net_log) OVERRIDE {
10694 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010695 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010696 }
10697
10698 virtual int ResolveFromCache(const RequestInfo& info,
10699 AddressList* addresses,
10700 const BoundNetLog& net_log) OVERRIDE {
10701 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10702 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910703 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610704 return rv;
10705 }
10706
[email protected]95a214c2011-08-04 21:50:4010707 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610708 host_resolver_.CancelRequest(req);
10709 }
10710
[email protected]46da33be2011-07-19 21:58:0410711 MockCachingHostResolver* GetMockHostResolver() {
10712 return &host_resolver_;
10713 }
10714
[email protected]e3ceb682011-06-28 23:55:4610715 private:
10716 MockCachingHostResolver host_resolver_;
10717 const HostPortPair host_port_;
10718};
10719
[email protected]45b170822012-05-04 21:18:1410720// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10721#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710722#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10723 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410724#else
[email protected]bb88e1d32013-05-03 23:11:0710725#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10726 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410727#endif
[email protected]23e482282013-06-14 16:08:0210728WRAPPED_TEST_P(HttpNetworkTransactionTest,
10729 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210730// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10731// prefix doesn't work with parametrized tests).
10732#if defined(OS_WIN)
10733 return;
10734#endif
10735
[email protected]e3ceb682011-06-28 23:55:4610736 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310737 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610738
10739 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610740 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410741 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710742 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610743 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710744 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610745 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10746 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610747
[email protected]8ddf8322012-02-23 18:08:0610748 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210749 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610751
[email protected]cdf8f7e72013-05-23 10:56:4610752 scoped_ptr<SpdyFrame> host1_req(
10753 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10754 scoped_ptr<SpdyFrame> host2_req(
10755 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610756 MockWrite spdy_writes[] = {
10757 CreateMockWrite(*host1_req, 1),
10758 CreateMockWrite(*host2_req, 4),
10759 };
[email protected]23e482282013-06-14 16:08:0210760 scoped_ptr<SpdyFrame> host1_resp(
10761 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10762 scoped_ptr<SpdyFrame> host1_resp_body(
10763 spdy_util_.ConstructSpdyBodyFrame(1, true));
10764 scoped_ptr<SpdyFrame> host2_resp(
10765 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10766 scoped_ptr<SpdyFrame> host2_resp_body(
10767 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610768 MockRead spdy_reads[] = {
10769 CreateMockRead(*host1_resp, 2),
10770 CreateMockRead(*host1_resp_body, 3),
10771 CreateMockRead(*host2_resp, 5),
10772 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610773 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610774 };
10775
[email protected]d2b5f092012-06-08 23:55:0210776 IPAddressNumber ip;
10777 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10778 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10779 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710780 OrderedSocketData spdy_data(
10781 connect,
10782 spdy_reads, arraysize(spdy_reads),
10783 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710784 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610785
[email protected]aa22b242011-11-16 18:58:2910786 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610787 HttpRequestInfo request1;
10788 request1.method = "GET";
10789 request1.url = GURL("https://www.google.com/");
10790 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010791 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610792
[email protected]49639fa2011-12-20 23:22:4110793 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610794 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110795 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610796
10797 const HttpResponseInfo* response = trans1.GetResponseInfo();
10798 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010799 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610800 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10801
10802 std::string response_data;
10803 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10804 EXPECT_EQ("hello!", response_data);
10805
10806 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1010807 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4610808 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010809 rv = host_resolver.Resolve(resolve_info,
10810 DEFAULT_PRIORITY,
10811 &ignored,
10812 callback.callback(),
10813 NULL,
10814 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710815 EXPECT_EQ(ERR_IO_PENDING, rv);
10816 rv = callback.WaitForResult();
10817 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610818
10819 HttpRequestInfo request2;
10820 request2.method = "GET";
10821 request2.url = GURL("https://www.gmail.com/");
10822 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010823 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610824
[email protected]49639fa2011-12-20 23:22:4110825 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610826 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110827 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610828
10829 response = trans2.GetResponseInfo();
10830 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010831 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610832 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10833 EXPECT_TRUE(response->was_fetched_via_spdy);
10834 EXPECT_TRUE(response->was_npn_negotiated);
10835 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10836 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610837}
[email protected]45b170822012-05-04 21:18:1410838#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4610839
[email protected]23e482282013-06-14 16:08:0210840TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910841 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610842 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910843 };
10844 MockRead data_reads2[] = {
10845 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10846 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610847 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910848 };
10849 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10850 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10851 StaticSocketDataProvider* data[] = { &data1, &data2 };
10852
10853 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10854
10855 EXPECT_EQ(OK, out.rv);
10856 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10857 EXPECT_EQ("hello world", out.response_data);
10858}
10859
[email protected]23e482282013-06-14 16:08:0210860TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910861 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0610862 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910863 };
10864 MockWrite data_writes2[] = {
10865 MockWrite("GET / HTTP/1.1\r\n"
10866 "Host: www.google.com\r\n"
10867 "Connection: keep-alive\r\n\r\n"),
10868 };
10869 MockRead data_reads2[] = {
10870 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10871 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610872 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910873 };
10874 StaticSocketDataProvider data1(NULL, 0,
10875 data_writes1, arraysize(data_writes1));
10876 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10877 data_writes2, arraysize(data_writes2));
10878 StaticSocketDataProvider* data[] = { &data1, &data2 };
10879
10880 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10881
10882 EXPECT_EQ(OK, out.rv);
10883 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10884 EXPECT_EQ("hello world", out.response_data);
10885}
10886
[email protected]23e482282013-06-14 16:08:0210887TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0410888 const std::string https_url = "https://www.google.com/";
10889 const std::string http_url = "http://www.google.com:443/";
10890
10891 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4610892 scoped_ptr<SpdyFrame> req1(
10893 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410894
10895 MockWrite writes1[] = {
10896 CreateMockWrite(*req1, 0),
10897 };
10898
[email protected]23e482282013-06-14 16:08:0210899 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10900 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0410901 MockRead reads1[] = {
10902 CreateMockRead(*resp1, 1),
10903 CreateMockRead(*body1, 2),
10904 MockRead(ASYNC, ERR_IO_PENDING, 3)
10905 };
10906
[email protected]dd54bd82012-07-19 23:44:5710907 DelayedSocketData data1(
10908 1, reads1, arraysize(reads1),
10909 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410910 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710911 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410912
10913 // HTTP GET for the HTTP URL
10914 MockWrite writes2[] = {
10915 MockWrite(ASYNC, 4,
10916 "GET / HTTP/1.1\r\n"
10917 "Host: www.google.com:443\r\n"
10918 "Connection: keep-alive\r\n\r\n"),
10919 };
10920
10921 MockRead reads2[] = {
10922 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10923 MockRead(ASYNC, 6, "hello"),
10924 MockRead(ASYNC, 7, OK),
10925 };
10926
[email protected]dd54bd82012-07-19 23:44:5710927 DelayedSocketData data2(
10928 1, reads2, arraysize(reads2),
10929 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0410930
[email protected]8450d722012-07-02 19:14:0410931 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210932 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10934 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10935 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0410936
[email protected]bb88e1d32013-05-03 23:11:0710937 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410938
10939 // Start the first transaction to set up the SpdySession
10940 HttpRequestInfo request1;
10941 request1.method = "GET";
10942 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410943 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010944 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410945 TestCompletionCallback callback1;
10946 EXPECT_EQ(ERR_IO_PENDING,
10947 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410948 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410949
10950 EXPECT_EQ(OK, callback1.WaitForResult());
10951 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
10952
10953 // Now, start the HTTP request
10954 HttpRequestInfo request2;
10955 request2.method = "GET";
10956 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0410957 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010958 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0410959 TestCompletionCallback callback2;
10960 EXPECT_EQ(ERR_IO_PENDING,
10961 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410962 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410963
10964 EXPECT_EQ(OK, callback2.WaitForResult());
10965 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
10966}
10967
[email protected]23e482282013-06-14 16:08:0210968TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0410969 const std::string https_url = "https://www.google.com/";
10970 const std::string http_url = "http://www.google.com:443/";
10971
10972 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5410973 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
10974 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4610975 scoped_ptr<SpdyFrame> req1(
10976 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410977
10978 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0210979 scoped_ptr<SpdyFrame> wrapped_req1(
10980 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0410981 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0210982 spdy_util_.GetMethodKey(), "GET",
10983 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
10984 spdy_util_.GetHostKey(), "www.google.com:443",
10985 spdy_util_.GetSchemeKey(), "http",
10986 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0410987 };
[email protected]4bd46222013-05-14 19:32:2310988 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
10989 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
10990 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0410991
10992 MockWrite writes1[] = {
10993 CreateMockWrite(*connect, 0),
10994 CreateMockWrite(*wrapped_req1, 2),
10995 CreateMockWrite(*req2, 5),
10996 };
10997
[email protected]23e482282013-06-14 16:08:0210998 scoped_ptr<SpdyFrame> conn_resp(
10999 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11000 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11001 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11002 scoped_ptr<SpdyFrame> wrapped_resp1(
11003 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11004 scoped_ptr<SpdyFrame> wrapped_body1(
11005 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11006 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11007 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411008 MockRead reads1[] = {
11009 CreateMockRead(*conn_resp, 1),
11010 CreateMockRead(*wrapped_resp1, 3),
11011 CreateMockRead(*wrapped_body1, 4),
11012 CreateMockRead(*resp2, 6),
11013 CreateMockRead(*body2, 7),
11014 MockRead(ASYNC, ERR_IO_PENDING, 8)
11015 };
11016
[email protected]dd54bd82012-07-19 23:44:5711017 DeterministicSocketData data1(reads1, arraysize(reads1),
11018 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411019 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711020 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411021
[email protected]bb88e1d32013-05-03 23:11:0711022 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211023 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11024 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711025 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411026 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211027 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711028 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411029 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211030 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711031 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11032 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411033
11034 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711035 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411036
11037 // Start the first transaction to set up the SpdySession
11038 HttpRequestInfo request1;
11039 request1.method = "GET";
11040 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411041 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011042 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411043 TestCompletionCallback callback1;
11044 EXPECT_EQ(ERR_IO_PENDING,
11045 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411046 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711047 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411048
11049 EXPECT_EQ(OK, callback1.WaitForResult());
11050 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11051
[email protected]f6c63db52013-02-02 00:35:2211052 LoadTimingInfo load_timing_info1;
11053 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11054 TestLoadTimingNotReusedWithPac(load_timing_info1,
11055 CONNECT_TIMING_HAS_SSL_TIMES);
11056
[email protected]8450d722012-07-02 19:14:0411057 // Now, start the HTTP request
11058 HttpRequestInfo request2;
11059 request2.method = "GET";
11060 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411061 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011062 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411063 TestCompletionCallback callback2;
11064 EXPECT_EQ(ERR_IO_PENDING,
11065 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411066 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711067 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411068
11069 EXPECT_EQ(OK, callback2.WaitForResult());
11070 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211071
11072 LoadTimingInfo load_timing_info2;
11073 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11074 // The established SPDY sessions is considered reused by the HTTP request.
11075 TestLoadTimingReusedWithPac(load_timing_info2);
11076 // HTTP requests over a SPDY session should have a different connection
11077 // socket_log_id than requests over a tunnel.
11078 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411079}
11080
[email protected]23e482282013-06-14 16:08:0211081TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411082 HttpStreamFactory::set_force_spdy_always(true);
11083 const std::string https_url = "https://www.google.com/";
11084 const std::string http_url = "http://www.google.com:443/";
11085
11086 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611087 scoped_ptr<SpdyFrame> req1(
11088 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411089 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611090 scoped_ptr<SpdyFrame> req2(
11091 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411092
11093 MockWrite writes[] = {
11094 CreateMockWrite(*req1, 1),
11095 CreateMockWrite(*req2, 4),
11096 };
11097
[email protected]23e482282013-06-14 16:08:0211098 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11099 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11100 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11101 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411102 MockRead reads[] = {
11103 CreateMockRead(*resp1, 2),
11104 CreateMockRead(*body1, 3),
11105 CreateMockRead(*resp2, 5),
11106 CreateMockRead(*body2, 6),
11107 MockRead(ASYNC, ERR_IO_PENDING, 7)
11108 };
11109
[email protected]dd54bd82012-07-19 23:44:5711110 OrderedSocketData data(reads, arraysize(reads),
11111 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411112
[email protected]8450d722012-07-02 19:14:0411113 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211114 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11116 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411117
[email protected]bb88e1d32013-05-03 23:11:0711118 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411119
11120 // Start the first transaction to set up the SpdySession
11121 HttpRequestInfo request1;
11122 request1.method = "GET";
11123 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411124 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011125 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411126 TestCompletionCallback callback1;
11127 EXPECT_EQ(ERR_IO_PENDING,
11128 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411129 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411130
11131 EXPECT_EQ(OK, callback1.WaitForResult());
11132 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11133
11134 // Now, start the HTTP request
11135 HttpRequestInfo request2;
11136 request2.method = "GET";
11137 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411138 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011139 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411140 TestCompletionCallback callback2;
11141 EXPECT_EQ(ERR_IO_PENDING,
11142 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411143 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411144
11145 EXPECT_EQ(OK, callback2.WaitForResult());
11146 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11147}
11148
[email protected]2d88e7d2012-07-19 17:55:1711149// Test that in the case where we have a SPDY session to a SPDY proxy
11150// that we do not pool other origins that resolve to the same IP when
11151// the certificate does not match the new origin.
11152// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211153TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711154 const std::string url1 = "http://www.google.com/";
11155 const std::string url2 = "https://mail.google.com/";
11156 const std::string ip_addr = "1.2.3.4";
11157
11158 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211159 scoped_ptr<SpdyHeaderBlock> headers(
11160 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311161 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211162 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711163
11164 MockWrite writes1[] = {
11165 CreateMockWrite(*req1, 0),
11166 };
11167
[email protected]23e482282013-06-14 16:08:0211168 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11169 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711170 MockRead reads1[] = {
11171 CreateMockRead(*resp1, 1),
11172 CreateMockRead(*body1, 2),
11173 MockRead(ASYNC, OK, 3) // EOF
11174 };
11175
11176 scoped_ptr<DeterministicSocketData> data1(
11177 new DeterministicSocketData(reads1, arraysize(reads1),
11178 writes1, arraysize(writes1)));
11179 IPAddressNumber ip;
11180 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11181 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11182 MockConnect connect_data1(ASYNC, OK, peer_addr);
11183 data1->set_connect_data(connect_data1);
11184
11185 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611186 scoped_ptr<SpdyFrame> req2(
11187 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711188
11189 MockWrite writes2[] = {
11190 CreateMockWrite(*req2, 0),
11191 };
11192
[email protected]23e482282013-06-14 16:08:0211193 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11194 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711195 MockRead reads2[] = {
11196 CreateMockRead(*resp2, 1),
11197 CreateMockRead(*body2, 2),
11198 MockRead(ASYNC, OK, 3) // EOF
11199 };
11200
11201 scoped_ptr<DeterministicSocketData> data2(
11202 new DeterministicSocketData(reads2, arraysize(reads2),
11203 writes2, arraysize(writes2)));
11204 MockConnect connect_data2(ASYNC, OK);
11205 data2->set_connect_data(connect_data2);
11206
11207 // Set up a proxy config that sends HTTP requests to a proxy, and
11208 // all others direct.
11209 ProxyConfig proxy_config;
11210 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11211 CapturingProxyResolver* capturing_proxy_resolver =
11212 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711213 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711214 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11215 NULL));
11216
11217 // Load a valid cert. Note, that this does not need to
11218 // be valid for proxy because the MockSSLClientSocket does
11219 // not actually verify it. But SpdySession will use this
11220 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511221 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711222 scoped_refptr<X509Certificate> server_cert(
11223 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11224 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11225
11226 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211227 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711228 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711229 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11230 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11231 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711232
11233 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211234 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711235 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11236 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11237 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711238
[email protected]bb88e1d32013-05-03 23:11:0711239 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11240 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11241 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711242
11243 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711244 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711245
11246 // Start the first transaction to set up the SpdySession
11247 HttpRequestInfo request1;
11248 request1.method = "GET";
11249 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711250 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011251 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711252 TestCompletionCallback callback1;
11253 ASSERT_EQ(ERR_IO_PENDING,
11254 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11255 data1->RunFor(3);
11256
11257 ASSERT_TRUE(callback1.have_result());
11258 EXPECT_EQ(OK, callback1.WaitForResult());
11259 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11260
11261 // Now, start the HTTP request
11262 HttpRequestInfo request2;
11263 request2.method = "GET";
11264 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711265 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011266 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711267 TestCompletionCallback callback2;
11268 EXPECT_EQ(ERR_IO_PENDING,
11269 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411270 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711271 data2->RunFor(3);
11272
11273 ASSERT_TRUE(callback2.have_result());
11274 EXPECT_EQ(OK, callback2.WaitForResult());
11275 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11276}
11277
[email protected]85f97342013-04-17 06:12:2411278// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11279// error) in SPDY session, removes the socket from pool and closes the SPDY
11280// session. Verify that new url's from the same HttpNetworkSession (and a new
11281// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211282TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411283 const std::string https_url = "https://www.google.com/";
11284
11285 MockRead reads1[] = {
11286 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11287 };
11288
11289 scoped_ptr<DeterministicSocketData> data1(
11290 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11291 data1->SetStop(1);
11292
[email protected]cdf8f7e72013-05-23 10:56:4611293 scoped_ptr<SpdyFrame> req2(
11294 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411295 MockWrite writes2[] = {
11296 CreateMockWrite(*req2, 0),
11297 };
11298
[email protected]23e482282013-06-14 16:08:0211299 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11300 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411301 MockRead reads2[] = {
11302 CreateMockRead(*resp2, 1),
11303 CreateMockRead(*body2, 2),
11304 MockRead(ASYNC, OK, 3) // EOF
11305 };
11306
11307 scoped_ptr<DeterministicSocketData> data2(
11308 new DeterministicSocketData(reads2, arraysize(reads2),
11309 writes2, arraysize(writes2)));
11310
[email protected]85f97342013-04-17 06:12:2411311 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211312 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711313 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11314 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11315 data1.get());
[email protected]85f97342013-04-17 06:12:2411316
11317 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211318 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711319 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11320 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11321 data2.get());
[email protected]85f97342013-04-17 06:12:2411322
11323 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711324 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411325
11326 // Start the first transaction to set up the SpdySession and verify that
11327 // connection was closed.
11328 HttpRequestInfo request1;
11329 request1.method = "GET";
11330 request1.url = GURL(https_url);
11331 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011332 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411333 TestCompletionCallback callback1;
11334 EXPECT_EQ(ERR_IO_PENDING,
11335 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411336 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411337 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11338
11339 // Now, start the second request and make sure it succeeds.
11340 HttpRequestInfo request2;
11341 request2.method = "GET";
11342 request2.url = GURL(https_url);
11343 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011344 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411345 TestCompletionCallback callback2;
11346 EXPECT_EQ(ERR_IO_PENDING,
11347 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411348 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411349 data2->RunFor(3);
11350
11351 ASSERT_TRUE(callback2.have_result());
11352 EXPECT_EQ(OK, callback2.WaitForResult());
11353 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11354}
11355
[email protected]23e482282013-06-14 16:08:0211356TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311357 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11358 ClientSocketPoolManager::set_max_sockets_per_group(
11359 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11360 ClientSocketPoolManager::set_max_sockets_per_pool(
11361 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11362
11363 // Use two different hosts with different IPs so they don't get pooled.
11364 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11365 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11366 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11367
11368 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211369 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311370 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211371 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11374
[email protected]cdf8f7e72013-05-23 10:56:4611375 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311376 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11377 MockWrite spdy1_writes[] = {
11378 CreateMockWrite(*host1_req, 1),
11379 };
[email protected]23e482282013-06-14 16:08:0211380 scoped_ptr<SpdyFrame> host1_resp(
11381 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11382 scoped_ptr<SpdyFrame> host1_resp_body(
11383 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311384 MockRead spdy1_reads[] = {
11385 CreateMockRead(*host1_resp, 2),
11386 CreateMockRead(*host1_resp_body, 3),
11387 MockRead(ASYNC, ERR_IO_PENDING, 4),
11388 };
11389
11390 scoped_ptr<OrderedSocketData> spdy1_data(
11391 new OrderedSocketData(
11392 spdy1_reads, arraysize(spdy1_reads),
11393 spdy1_writes, arraysize(spdy1_writes)));
11394 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11395
[email protected]cdf8f7e72013-05-23 10:56:4611396 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311397 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11398 MockWrite spdy2_writes[] = {
11399 CreateMockWrite(*host2_req, 1),
11400 };
[email protected]23e482282013-06-14 16:08:0211401 scoped_ptr<SpdyFrame> host2_resp(
11402 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11403 scoped_ptr<SpdyFrame> host2_resp_body(
11404 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311405 MockRead spdy2_reads[] = {
11406 CreateMockRead(*host2_resp, 2),
11407 CreateMockRead(*host2_resp_body, 3),
11408 MockRead(ASYNC, ERR_IO_PENDING, 4),
11409 };
11410
11411 scoped_ptr<OrderedSocketData> spdy2_data(
11412 new OrderedSocketData(
11413 spdy2_reads, arraysize(spdy2_reads),
11414 spdy2_writes, arraysize(spdy2_writes)));
11415 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11416
11417 MockWrite http_write[] = {
11418 MockWrite("GET / HTTP/1.1\r\n"
11419 "Host: www.a.com\r\n"
11420 "Connection: keep-alive\r\n\r\n"),
11421 };
11422
11423 MockRead http_read[] = {
11424 MockRead("HTTP/1.1 200 OK\r\n"),
11425 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11426 MockRead("Content-Length: 6\r\n\r\n"),
11427 MockRead("hello!"),
11428 };
11429 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11430 http_write, arraysize(http_write));
11431 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11432
11433 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011434 SpdySessionKey spdy_session_key_a(
11435 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311436 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611437 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311438
11439 TestCompletionCallback callback;
11440 HttpRequestInfo request1;
11441 request1.method = "GET";
11442 request1.url = GURL("https://www.a.com/");
11443 request1.load_flags = 0;
11444 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011445 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311446
11447 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11448 EXPECT_EQ(ERR_IO_PENDING, rv);
11449 EXPECT_EQ(OK, callback.WaitForResult());
11450
11451 const HttpResponseInfo* response = trans->GetResponseInfo();
11452 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011453 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311454 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11455 EXPECT_TRUE(response->was_fetched_via_spdy);
11456 EXPECT_TRUE(response->was_npn_negotiated);
11457
11458 std::string response_data;
11459 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11460 EXPECT_EQ("hello!", response_data);
11461 trans.reset();
11462 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611463 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311464
11465 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011466 SpdySessionKey spdy_session_key_b(
11467 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311468 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611469 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311470 HttpRequestInfo request2;
11471 request2.method = "GET";
11472 request2.url = GURL("https://www.b.com/");
11473 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011474 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311475
11476 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11477 EXPECT_EQ(ERR_IO_PENDING, rv);
11478 EXPECT_EQ(OK, callback.WaitForResult());
11479
11480 response = trans->GetResponseInfo();
11481 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011482 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311483 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11484 EXPECT_TRUE(response->was_fetched_via_spdy);
11485 EXPECT_TRUE(response->was_npn_negotiated);
11486 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11487 EXPECT_EQ("hello!", response_data);
11488 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611489 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311490 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611491 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311492
11493 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011494 SpdySessionKey spdy_session_key_a1(
11495 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311496 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611497 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311498 HttpRequestInfo request3;
11499 request3.method = "GET";
11500 request3.url = GURL("http://www.a.com/");
11501 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011502 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311503
11504 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11505 EXPECT_EQ(ERR_IO_PENDING, rv);
11506 EXPECT_EQ(OK, callback.WaitForResult());
11507
11508 response = trans->GetResponseInfo();
11509 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011510 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311511 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11512 EXPECT_FALSE(response->was_fetched_via_spdy);
11513 EXPECT_FALSE(response->was_npn_negotiated);
11514 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11515 EXPECT_EQ("hello!", response_data);
11516 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611517 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311518 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611519 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311520}
11521
[email protected]79e1fd62013-06-20 06:50:0411522TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11523 HttpRequestInfo request;
11524 request.method = "GET";
11525 request.url = GURL("http://www.google.com/");
11526 request.load_flags = 0;
11527
11528 scoped_ptr<HttpTransaction> trans(
11529 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11530 CreateSession(&session_deps_)));
11531
11532 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11533 StaticSocketDataProvider data;
11534 data.set_connect_data(mock_connect);
11535 session_deps_.socket_factory->AddSocketDataProvider(&data);
11536
11537 TestCompletionCallback callback;
11538
11539 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11540 EXPECT_EQ(ERR_IO_PENDING, rv);
11541
11542 rv = callback.WaitForResult();
11543 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11544
11545 EXPECT_EQ(NULL, trans->GetResponseInfo());
11546
11547 // We don't care whether this succeeds or fails, but it shouldn't crash.
11548 HttpRequestHeaders request_headers;
11549 trans->GetFullRequestHeaders(&request_headers);
11550}
11551
11552TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11553 HttpRequestInfo request;
11554 request.method = "GET";
11555 request.url = GURL("http://www.google.com/");
11556 request.load_flags = 0;
11557
11558 scoped_ptr<HttpTransaction> trans(
11559 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11560 CreateSession(&session_deps_)));
11561
11562 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11563 StaticSocketDataProvider data;
11564 data.set_connect_data(mock_connect);
11565 session_deps_.socket_factory->AddSocketDataProvider(&data);
11566
11567 TestCompletionCallback callback;
11568
11569 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11570 EXPECT_EQ(ERR_IO_PENDING, rv);
11571
11572 rv = callback.WaitForResult();
11573 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11574
11575 EXPECT_EQ(NULL, trans->GetResponseInfo());
11576
11577 // We don't care whether this succeeds or fails, but it shouldn't crash.
11578 HttpRequestHeaders request_headers;
11579 trans->GetFullRequestHeaders(&request_headers);
11580}
11581
11582TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11583 HttpRequestInfo request;
11584 request.method = "GET";
11585 request.url = GURL("http://www.google.com/");
11586 request.load_flags = 0;
11587
11588 scoped_ptr<HttpTransaction> trans(
11589 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11590 CreateSession(&session_deps_)));
11591
11592 MockWrite data_writes[] = {
11593 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11594 };
11595 MockRead data_reads[] = {
11596 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11597 };
11598
11599 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11600 data_writes, arraysize(data_writes));
11601 session_deps_.socket_factory->AddSocketDataProvider(&data);
11602
11603 TestCompletionCallback callback;
11604
11605 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11606 EXPECT_EQ(ERR_IO_PENDING, rv);
11607
11608 rv = callback.WaitForResult();
11609 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11610
11611 EXPECT_EQ(NULL, trans->GetResponseInfo());
11612
11613 HttpRequestHeaders request_headers;
11614 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11615 EXPECT_TRUE(request_headers.HasHeader("Host"));
11616}
11617
11618TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11619 HttpRequestInfo request;
11620 request.method = "GET";
11621 request.url = GURL("http://www.google.com/");
11622 request.load_flags = 0;
11623
11624 scoped_ptr<HttpTransaction> trans(
11625 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11626 CreateSession(&session_deps_)));
11627
11628 MockWrite data_writes[] = {
11629 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11630 };
11631 MockRead data_reads[] = {
11632 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11633 };
11634
11635 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11636 data_writes, arraysize(data_writes));
11637 session_deps_.socket_factory->AddSocketDataProvider(&data);
11638
11639 TestCompletionCallback callback;
11640
11641 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11642 EXPECT_EQ(ERR_IO_PENDING, rv);
11643
11644 rv = callback.WaitForResult();
11645 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11646
11647 EXPECT_EQ(NULL, trans->GetResponseInfo());
11648
11649 HttpRequestHeaders request_headers;
11650 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11651 EXPECT_TRUE(request_headers.HasHeader("Host"));
11652}
11653
11654TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11655 HttpRequestInfo request;
11656 request.method = "GET";
11657 request.url = GURL("http://www.google.com/");
11658 request.load_flags = 0;
11659
11660 scoped_ptr<HttpTransaction> trans(
11661 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11662 CreateSession(&session_deps_)));
11663
11664 MockWrite data_writes[] = {
11665 MockWrite("GET / HTTP/1.1\r\n"
11666 "Host: www.google.com\r\n"
11667 "Connection: keep-alive\r\n\r\n"),
11668 };
11669 MockRead data_reads[] = {
11670 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11671 };
11672
11673 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11674 data_writes, arraysize(data_writes));
11675 session_deps_.socket_factory->AddSocketDataProvider(&data);
11676
11677 TestCompletionCallback callback;
11678
11679 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11680 EXPECT_EQ(ERR_IO_PENDING, rv);
11681
11682 rv = callback.WaitForResult();
11683 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11684
11685 EXPECT_EQ(NULL, trans->GetResponseInfo());
11686
11687 HttpRequestHeaders request_headers;
11688 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11689 EXPECT_TRUE(request_headers.HasHeader("Host"));
11690}
11691
11692TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11693 HttpRequestInfo request;
11694 request.method = "GET";
11695 request.url = GURL("http://www.google.com/");
11696 request.load_flags = 0;
11697
11698 scoped_ptr<HttpTransaction> trans(
11699 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11700 CreateSession(&session_deps_)));
11701
11702 MockWrite data_writes[] = {
11703 MockWrite("GET / HTTP/1.1\r\n"
11704 "Host: www.google.com\r\n"
11705 "Connection: keep-alive\r\n\r\n"),
11706 };
11707 MockRead data_reads[] = {
11708 MockRead(ASYNC, ERR_CONNECTION_RESET),
11709 };
11710
11711 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11712 data_writes, arraysize(data_writes));
11713 session_deps_.socket_factory->AddSocketDataProvider(&data);
11714
11715 TestCompletionCallback callback;
11716
11717 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11718 EXPECT_EQ(ERR_IO_PENDING, rv);
11719
11720 rv = callback.WaitForResult();
11721 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11722
11723 EXPECT_EQ(NULL, trans->GetResponseInfo());
11724
11725 HttpRequestHeaders request_headers;
11726 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11727 EXPECT_TRUE(request_headers.HasHeader("Host"));
11728}
11729
11730TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11731 HttpRequestInfo request;
11732 request.method = "GET";
11733 request.url = GURL("http://www.google.com/");
11734 request.load_flags = 0;
11735 request.extra_headers.SetHeader("X-Foo", "bar");
11736
11737 scoped_ptr<HttpTransaction> trans(
11738 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11739 CreateSession(&session_deps_)));
11740
11741 MockWrite data_writes[] = {
11742 MockWrite("GET / HTTP/1.1\r\n"
11743 "Host: www.google.com\r\n"
11744 "Connection: keep-alive\r\n"
11745 "X-Foo: bar\r\n\r\n"),
11746 };
11747 MockRead data_reads[] = {
11748 MockRead("HTTP/1.1 200 OK\r\n"
11749 "Content-Length: 5\r\n\r\n"
11750 "hello"),
11751 MockRead(ASYNC, ERR_UNEXPECTED),
11752 };
11753
11754 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11755 data_writes, arraysize(data_writes));
11756 session_deps_.socket_factory->AddSocketDataProvider(&data);
11757
11758 TestCompletionCallback callback;
11759
11760 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11761 EXPECT_EQ(ERR_IO_PENDING, rv);
11762
11763 rv = callback.WaitForResult();
11764 EXPECT_EQ(OK, rv);
11765
11766 HttpRequestHeaders request_headers;
11767 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11768 std::string foo;
11769 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11770 EXPECT_EQ("bar", foo);
11771}
11772
[email protected]bf828982013-08-14 18:01:4711773namespace {
11774
[email protected]e86839fd2013-08-14 18:29:0311775// Fake HttpStreamBase that simply records calls to SetPriority().
11776class FakeStream : public HttpStreamBase,
11777 public base::SupportsWeakPtr<FakeStream> {
11778 public:
11779 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
11780 virtual ~FakeStream() {}
11781
11782 RequestPriority priority() const { return priority_; }
11783
11784 virtual int InitializeStream(const HttpRequestInfo* request_info,
11785 RequestPriority priority,
11786 const BoundNetLog& net_log,
11787 const CompletionCallback& callback) OVERRIDE {
11788 return ERR_IO_PENDING;
11789 }
11790
11791 virtual int SendRequest(const HttpRequestHeaders& request_headers,
11792 HttpResponseInfo* response,
11793 const CompletionCallback& callback) OVERRIDE {
11794 ADD_FAILURE();
11795 return ERR_UNEXPECTED;
11796 }
11797
11798 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
11799 ADD_FAILURE();
11800 return ERR_UNEXPECTED;
11801 }
11802
11803 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
11804 ADD_FAILURE();
11805 return NULL;
11806 }
11807
11808 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
11809 const CompletionCallback& callback) OVERRIDE {
11810 ADD_FAILURE();
11811 return ERR_UNEXPECTED;
11812 }
11813
11814 virtual void Close(bool not_reusable) OVERRIDE {}
11815
11816 virtual bool IsResponseBodyComplete() const OVERRIDE {
11817 ADD_FAILURE();
11818 return false;
11819 }
11820
11821 virtual bool CanFindEndOfResponse() const OVERRIDE {
11822 return false;
11823 }
11824
11825 virtual bool IsConnectionReused() const OVERRIDE {
11826 ADD_FAILURE();
11827 return false;
11828 }
11829
11830 virtual void SetConnectionReused() OVERRIDE {
11831 ADD_FAILURE();
11832 }
11833
11834 virtual bool IsConnectionReusable() const OVERRIDE {
11835 ADD_FAILURE();
11836 return false;
11837 }
11838
11839 virtual bool GetLoadTimingInfo(
11840 LoadTimingInfo* load_timing_info) const OVERRIDE {
11841 ADD_FAILURE();
11842 return false;
11843 }
11844
11845 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
11846 ADD_FAILURE();
11847 }
11848
11849 virtual void GetSSLCertRequestInfo(
11850 SSLCertRequestInfo* cert_request_info) OVERRIDE {
11851 ADD_FAILURE();
11852 }
11853
11854 virtual bool IsSpdyHttpStream() const OVERRIDE {
11855 ADD_FAILURE();
11856 return false;
11857 }
11858
11859 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
11860 ADD_FAILURE();
11861 }
11862
11863 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11864 priority_ = priority;
11865 }
11866
11867 private:
11868 RequestPriority priority_;
11869
11870 DISALLOW_COPY_AND_ASSIGN(FakeStream);
11871};
11872
11873// Fake HttpStreamRequest that simply records calls to SetPriority()
11874// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4711875class FakeStreamRequest : public HttpStreamRequest,
11876 public base::SupportsWeakPtr<FakeStreamRequest> {
11877 public:
[email protected]e86839fd2013-08-14 18:29:0311878 FakeStreamRequest(RequestPriority priority,
11879 HttpStreamRequest::Delegate* delegate)
11880 : priority_(priority),
11881 delegate_(delegate) {}
11882
[email protected]bf828982013-08-14 18:01:4711883 virtual ~FakeStreamRequest() {}
11884
11885 RequestPriority priority() const { return priority_; }
11886
[email protected]e86839fd2013-08-14 18:29:0311887 // Create a new FakeStream and pass it to the request's
11888 // delegate. Returns a weak pointer to the FakeStream.
11889 base::WeakPtr<FakeStream> FinishStreamRequest() {
11890 FakeStream* fake_stream = new FakeStream(priority_);
11891 // Do this before calling OnStreamReady() as OnStreamReady() may
11892 // immediately delete |fake_stream|.
11893 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
11894 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
11895 return weak_stream;
11896 }
11897
[email protected]bf828982013-08-14 18:01:4711898 virtual int RestartTunnelWithProxyAuth(
11899 const AuthCredentials& credentials) OVERRIDE {
11900 ADD_FAILURE();
11901 return ERR_UNEXPECTED;
11902 }
11903
11904 virtual LoadState GetLoadState() const OVERRIDE {
11905 ADD_FAILURE();
11906 return LoadState();
11907 }
11908
11909 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11910 priority_ = priority;
11911 }
11912
11913 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711914 return false;
11915 }
11916
11917 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711918 return kProtoUnknown;
11919 }
11920
11921 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4711922 return false;
11923 }
11924
11925 private:
11926 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0311927 HttpStreamRequest::Delegate* const delegate_;
[email protected]bf828982013-08-14 18:01:4711928
11929 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
11930};
11931
11932// Fake HttpStreamFactory that vends FakeStreamRequests.
11933class FakeStreamFactory : public HttpStreamFactory {
11934 public:
11935 FakeStreamFactory() {}
11936 virtual ~FakeStreamFactory() {}
11937
11938 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
11939 // RequestStream() (which may be NULL if it was destroyed already).
11940 base::WeakPtr<FakeStreamRequest> last_stream_request() {
11941 return last_stream_request_;
11942 }
11943
11944 virtual HttpStreamRequest* RequestStream(
11945 const HttpRequestInfo& info,
11946 RequestPriority priority,
11947 const SSLConfig& server_ssl_config,
11948 const SSLConfig& proxy_ssl_config,
11949 HttpStreamRequest::Delegate* delegate,
11950 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0311951 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4711952 last_stream_request_ = fake_request->AsWeakPtr();
11953 return fake_request;
11954 }
11955
11956 virtual HttpStreamRequest* RequestWebSocketStream(
11957 const HttpRequestInfo& info,
11958 RequestPriority priority,
11959 const SSLConfig& server_ssl_config,
11960 const SSLConfig& proxy_ssl_config,
11961 HttpStreamRequest::Delegate* delegate,
11962 WebSocketStreamBase::Factory* factory,
11963 const BoundNetLog& net_log) OVERRIDE {
11964 ADD_FAILURE();
11965 return NULL;
11966 }
11967
11968 virtual void PreconnectStreams(int num_streams,
11969 const HttpRequestInfo& info,
11970 RequestPriority priority,
11971 const SSLConfig& server_ssl_config,
11972 const SSLConfig& proxy_ssl_config) OVERRIDE {
11973 ADD_FAILURE();
11974 }
11975
11976 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
11977 ADD_FAILURE();
11978 return NULL;
11979 }
11980
11981 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
11982 ADD_FAILURE();
11983 return NULL;
11984 }
11985
11986 private:
11987 base::WeakPtr<FakeStreamRequest> last_stream_request_;
11988
11989 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
11990};
11991
11992} // namespace
11993
11994// Make sure that HttpNetworkTransaction passes on its priority to its
11995// stream request on start.
11996TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
11997 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11998 HttpNetworkSessionPeer peer(session);
11999 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12000 peer.SetHttpStreamFactory(fake_factory);
12001
12002 HttpNetworkTransaction trans(LOW, session);
12003
12004 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12005
12006 HttpRequestInfo request;
12007 TestCompletionCallback callback;
12008 EXPECT_EQ(ERR_IO_PENDING,
12009 trans.Start(&request, callback.callback(), BoundNetLog()));
12010
12011 base::WeakPtr<FakeStreamRequest> fake_request =
12012 fake_factory->last_stream_request();
12013 ASSERT_TRUE(fake_request != NULL);
12014 EXPECT_EQ(LOW, fake_request->priority());
12015}
12016
12017// Make sure that HttpNetworkTransaction passes on its priority
12018// updates to its stream request.
12019TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12020 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12021 HttpNetworkSessionPeer peer(session);
12022 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12023 peer.SetHttpStreamFactory(fake_factory);
12024
12025 HttpNetworkTransaction trans(LOW, session);
12026
12027 HttpRequestInfo request;
12028 TestCompletionCallback callback;
12029 EXPECT_EQ(ERR_IO_PENDING,
12030 trans.Start(&request, callback.callback(), BoundNetLog()));
12031
12032 base::WeakPtr<FakeStreamRequest> fake_request =
12033 fake_factory->last_stream_request();
12034 ASSERT_TRUE(fake_request != NULL);
12035 EXPECT_EQ(LOW, fake_request->priority());
12036
12037 trans.SetPriority(LOWEST);
12038 ASSERT_TRUE(fake_request != NULL);
12039 EXPECT_EQ(LOWEST, fake_request->priority());
12040}
12041
[email protected]e86839fd2013-08-14 18:29:0312042// Make sure that HttpNetworkTransaction passes on its priority
12043// updates to its stream.
12044TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12046 HttpNetworkSessionPeer peer(session);
12047 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12048 peer.SetHttpStreamFactory(fake_factory);
12049
12050 HttpNetworkTransaction trans(LOW, session);
12051
12052 HttpRequestInfo request;
12053 TestCompletionCallback callback;
12054 EXPECT_EQ(ERR_IO_PENDING,
12055 trans.Start(&request, callback.callback(), BoundNetLog()));
12056
12057 base::WeakPtr<FakeStreamRequest> fake_request =
12058 fake_factory->last_stream_request();
12059 ASSERT_TRUE(fake_request != NULL);
12060 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12061 ASSERT_TRUE(fake_stream != NULL);
12062 EXPECT_EQ(LOW, fake_stream->priority());
12063
12064 trans.SetPriority(LOWEST);
12065 EXPECT_EQ(LOWEST, fake_stream->priority());
12066}
12067
[email protected]043b68c82013-08-22 23:41:5212068// Tests that when a used socket is returned to the SSL socket pool, it's closed
12069// if the transport socket pool is stalled on the global socket limit.
12070TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12071 ClientSocketPoolManager::set_max_sockets_per_group(
12072 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12073 ClientSocketPoolManager::set_max_sockets_per_pool(
12074 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12075
12076 // Set up SSL request.
12077
12078 HttpRequestInfo ssl_request;
12079 ssl_request.method = "GET";
12080 ssl_request.url = GURL("https://www.google.com/");
12081
12082 MockWrite ssl_writes[] = {
12083 MockWrite("GET / HTTP/1.1\r\n"
12084 "Host: www.google.com\r\n"
12085 "Connection: keep-alive\r\n\r\n"),
12086 };
12087 MockRead ssl_reads[] = {
12088 MockRead("HTTP/1.1 200 OK\r\n"),
12089 MockRead("Content-Length: 11\r\n\r\n"),
12090 MockRead("hello world"),
12091 MockRead(SYNCHRONOUS, OK),
12092 };
12093 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12094 ssl_writes, arraysize(ssl_writes));
12095 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12096
12097 SSLSocketDataProvider ssl(ASYNC, OK);
12098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12099
12100 // Set up HTTP request.
12101
12102 HttpRequestInfo http_request;
12103 http_request.method = "GET";
12104 http_request.url = GURL("http://www.google.com/");
12105
12106 MockWrite http_writes[] = {
12107 MockWrite("GET / HTTP/1.1\r\n"
12108 "Host: www.google.com\r\n"
12109 "Connection: keep-alive\r\n\r\n"),
12110 };
12111 MockRead http_reads[] = {
12112 MockRead("HTTP/1.1 200 OK\r\n"),
12113 MockRead("Content-Length: 7\r\n\r\n"),
12114 MockRead("falafel"),
12115 MockRead(SYNCHRONOUS, OK),
12116 };
12117 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12118 http_writes, arraysize(http_writes));
12119 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12120
12121 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12122
12123 // Start the SSL request.
12124 TestCompletionCallback ssl_callback;
12125 scoped_ptr<HttpTransaction> ssl_trans(
12126 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12127 ASSERT_EQ(ERR_IO_PENDING,
12128 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12129 BoundNetLog()));
12130
12131 // Start the HTTP request. Pool should stall.
12132 TestCompletionCallback http_callback;
12133 scoped_ptr<HttpTransaction> http_trans(
12134 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12135 ASSERT_EQ(ERR_IO_PENDING,
12136 http_trans->Start(&http_request, http_callback.callback(),
12137 BoundNetLog()));
12138 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12139
12140 // Wait for response from SSL request.
12141 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12142 std::string response_data;
12143 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12144 EXPECT_EQ("hello world", response_data);
12145
12146 // The SSL socket should automatically be closed, so the HTTP request can
12147 // start.
12148 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12149 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12150
12151 // The HTTP request can now complete.
12152 ASSERT_EQ(OK, http_callback.WaitForResult());
12153 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12154 EXPECT_EQ("falafel", response_data);
12155
12156 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12157}
12158
12159// Tests that when a SSL connection is established but there's no corresponding
12160// request that needs it, the new socket is closed if the transport socket pool
12161// is stalled on the global socket limit.
12162TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12163 ClientSocketPoolManager::set_max_sockets_per_group(
12164 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12165 ClientSocketPoolManager::set_max_sockets_per_pool(
12166 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12167
12168 // Set up an ssl request.
12169
12170 HttpRequestInfo ssl_request;
12171 ssl_request.method = "GET";
12172 ssl_request.url = GURL("https://www.foopy.com/");
12173
12174 // No data will be sent on the SSL socket.
12175 StaticSocketDataProvider ssl_data;
12176 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12177
12178 SSLSocketDataProvider ssl(ASYNC, OK);
12179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12180
12181 // Set up HTTP request.
12182
12183 HttpRequestInfo http_request;
12184 http_request.method = "GET";
12185 http_request.url = GURL("http://www.google.com/");
12186
12187 MockWrite http_writes[] = {
12188 MockWrite("GET / HTTP/1.1\r\n"
12189 "Host: www.google.com\r\n"
12190 "Connection: keep-alive\r\n\r\n"),
12191 };
12192 MockRead http_reads[] = {
12193 MockRead("HTTP/1.1 200 OK\r\n"),
12194 MockRead("Content-Length: 7\r\n\r\n"),
12195 MockRead("falafel"),
12196 MockRead(SYNCHRONOUS, OK),
12197 };
12198 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12199 http_writes, arraysize(http_writes));
12200 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12201
12202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12203
12204 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12205 // cancelled when a normal transaction is cancelled.
12206 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12207 net::SSLConfig ssl_config;
12208 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12209 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12210 ssl_config, ssl_config);
12211 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12212
12213 // Start the HTTP request. Pool should stall.
12214 TestCompletionCallback http_callback;
12215 scoped_ptr<HttpTransaction> http_trans(
12216 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12217 ASSERT_EQ(ERR_IO_PENDING,
12218 http_trans->Start(&http_request, http_callback.callback(),
12219 BoundNetLog()));
12220 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12221
12222 // The SSL connection will automatically be closed once the connection is
12223 // established, to let the HTTP request start.
12224 ASSERT_EQ(OK, http_callback.WaitForResult());
12225 std::string response_data;
12226 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12227 EXPECT_EQ("falafel", response_data);
12228
12229 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12230}
12231
[email protected]89ceba9a2009-03-21 03:46:0612232} // namespace net