blob: c1ed89ba16078e3898835e22939de8d9b0da47a9 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
9#include <string>
[email protected]95d88ffe2010-02-04 21:25:3310#include <vector>
[email protected]77848d12008-11-14 00:00:2211
[email protected]2d731a32010-04-29 01:04:0612#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3013#include "base/compiler_specific.h"
[email protected]95d88ffe2010-02-04 21:25:3314#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:5215#include "base/files/file_path.h"
[email protected]f3da152d2012-06-02 01:00:5716#include "base/json/json_writer.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4718#include "base/memory/weak_ptr.h"
[email protected]125ef482013-06-11 18:32:4719#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0520#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3321#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3522#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1223#include "net/base/capturing_net_log.h"
[email protected]bacff652009-03-31 17:50:3324#include "net/base/completion_callback.h"
[email protected]58e32bb2013-01-21 18:23:2525#include "net/base/load_timing_info.h"
26#include "net/base/load_timing_info_test_util.h"
[email protected]169d0012010-05-10 23:20:1227#include "net/base/net_log.h"
28#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3129#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5230#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4031#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0632#include "net/base/upload_bytes_element_reader.h"
[email protected]329b68b2012-11-14 17:54:2733#include "net/base/upload_data_stream.h"
[email protected]d98961652012-09-11 20:27:2134#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1135#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1636#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5337#include "net/dns/mock_host_resolver.h"
[email protected]3c32c5f2010-05-18 15:18:1238#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0039#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2940#include "net/http/http_auth_handler_ntlm.h"
[email protected]0877e3d2009-10-17 22:29:5741#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5242#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5643#include "net/http/http_network_session_peer.h"
[email protected]17291a022011-10-10 07:32:5344#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5745#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3846#include "net/http/http_stream_factory.h"
initial.commit586acc5fe2008-07-26 22:42:5247#include "net/http/http_transaction_unittest.h"
[email protected]51fff29d2008-12-19 22:17:5348#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0349#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1150#include "net/proxy/proxy_resolver.h"
51#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4452#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0353#include "net/socket/client_socket_pool_manager.h"
[email protected]a42dbd142011-11-17 16:42:0254#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0755#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4456#include "net/socket/socket_test_util.h"
57#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5458#include "net/spdy/spdy_framer.h"
59#include "net/spdy/spdy_session.h"
60#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0261#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5762#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0363#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5764#include "net/ssl/ssl_config_service_defaults.h"
65#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1166#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4467#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5268#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1569#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2770#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5271
[email protected]ad65a3e2013-12-25 18:18:0172using base::ASCIIToUTF16;
73
initial.commit586acc5fe2008-07-26 22:42:5274//-----------------------------------------------------------------------------
75
[email protected]13c8a092010-07-29 06:15:4476namespace {
77
[email protected]42cba2fb2013-03-29 19:58:5778const base::string16 kBar(ASCIIToUTF16("bar"));
79const base::string16 kBar2(ASCIIToUTF16("bar2"));
80const base::string16 kBar3(ASCIIToUTF16("bar3"));
81const base::string16 kBaz(ASCIIToUTF16("baz"));
82const base::string16 kFirst(ASCIIToUTF16("first"));
83const base::string16 kFoo(ASCIIToUTF16("foo"));
84const base::string16 kFoo2(ASCIIToUTF16("foo2"));
85const base::string16 kFoo3(ASCIIToUTF16("foo3"));
86const base::string16 kFou(ASCIIToUTF16("fou"));
87const base::string16 kSecond(ASCIIToUTF16("second"));
88const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
89const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4490
[email protected]e5c026642012-03-17 00:14:0291int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
92 return session->GetTransportSocketPool(
93 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
94}
95
96int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
97 return session->GetSSLSocketPool(
98 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
99}
100
[email protected]043b68c82013-08-22 23:41:52101bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
102 return session->GetTransportSocketPool(
103 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
104}
105
[email protected]f3da152d2012-06-02 01:00:57106// Takes in a Value created from a NetLogHttpResponseParameter, and returns
107// a JSONified list of headers as a single string. Uses single quotes instead
108// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27109bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57110 if (!params)
111 return false;
[email protected]ea5ef4c2013-06-13 22:50:27112 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57113 if (!params->GetList("headers", &header_list))
114 return false;
115 std::string double_quote_headers;
116 base::JSONWriter::Write(header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28117 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57118 return true;
119}
120
[email protected]029c83b62013-01-24 05:28:20121// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
122// used.
123void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
124 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25125 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
126
[email protected]029c83b62013-01-24 05:28:20127 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
128 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
129
130 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
131 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25132
133 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25134
[email protected]3b23a222013-05-15 21:33:25135 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25136 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
137 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25138 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25139}
140
[email protected]029c83b62013-01-24 05:28:20141// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
142// used.
[email protected]58e32bb2013-01-21 18:23:25143void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
144 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20145 EXPECT_FALSE(load_timing_info.socket_reused);
146 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
147
148 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
149 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
150
151 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25152 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20153 EXPECT_LE(load_timing_info.connect_timing.connect_end,
154 load_timing_info.send_start);
155
156 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20157
[email protected]3b23a222013-05-15 21:33:25158 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20159 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
160 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25161 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20162}
163
164// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
165// used.
166void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
167 EXPECT_TRUE(load_timing_info.socket_reused);
168 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
169
170 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
171
172 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
173 EXPECT_LE(load_timing_info.proxy_resolve_start,
174 load_timing_info.proxy_resolve_end);
175 EXPECT_LE(load_timing_info.proxy_resolve_end,
176 load_timing_info.send_start);
177 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20178
[email protected]3b23a222013-05-15 21:33:25179 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20180 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
181 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25182 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20183}
184
185// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
186// used.
187void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
188 int connect_timing_flags) {
189 EXPECT_FALSE(load_timing_info.socket_reused);
190 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
191
192 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
193 EXPECT_LE(load_timing_info.proxy_resolve_start,
194 load_timing_info.proxy_resolve_end);
195 EXPECT_LE(load_timing_info.proxy_resolve_end,
196 load_timing_info.connect_timing.connect_start);
197 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
198 connect_timing_flags);
199 EXPECT_LE(load_timing_info.connect_timing.connect_end,
200 load_timing_info.send_start);
201
202 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20203
[email protected]3b23a222013-05-15 21:33:25204 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20205 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
206 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25207 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25208}
209
[email protected]13c8a092010-07-29 06:15:44210} // namespace
211
[email protected]89ceba9a2009-03-21 03:46:06212namespace net {
213
[email protected]448d4ca52012-03-04 04:12:23214namespace {
215
[email protected]c6bf8152012-12-02 07:43:34216HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
217 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14218}
219
[email protected]448d4ca52012-03-04 04:12:23220} // namespace
221
[email protected]23e482282013-06-14 16:08:02222class HttpNetworkTransactionTest
223 : public PlatformTest,
224 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03225 public:
[email protected]23e482282013-06-14 16:08:02226 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03227 // Important to restore the per-pool limit first, since the pool limit must
228 // always be greater than group limit, and the tests reduce both limits.
229 ClientSocketPoolManager::set_max_sockets_per_pool(
230 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
231 ClientSocketPoolManager::set_max_sockets_per_group(
232 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
233 }
234
[email protected]e3ceb682011-06-28 23:55:46235 protected:
[email protected]23e482282013-06-14 16:08:02236 HttpNetworkTransactionTest()
237 : spdy_util_(GetParam()),
238 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03239 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
240 HttpNetworkSession::NORMAL_SOCKET_POOL)),
241 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
242 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
243 }
[email protected]bb88e1d32013-05-03 23:11:07244
[email protected]e3ceb682011-06-28 23:55:46245 struct SimpleGetHelperResult {
246 int rv;
247 std::string status_line;
248 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19249 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25250 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46251 };
252
[email protected]2ff8b312010-04-26 22:20:54253 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50254 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34255 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54256 }
257
[email protected]0e75a732008-10-16 20:36:09258 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50259 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34260 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09261 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34262 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09263 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50264 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34265 base::MessageLoop::current()->RunUntilIdle();
[email protected]c54c6962013-02-01 04:53:19266 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:16267 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]0e75a732008-10-16 20:36:09268 }
269
[email protected]8a0fc822013-06-27 20:52:43270 // This is the expected return from a current server advertising SPDY.
271 std::string GetAlternateProtocolHttpHeader() {
272 return
273 std::string("Alternate-Protocol: 443:") +
274 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
275 "\r\n\r\n";
276 }
277
[email protected]202965992011-12-07 23:04:51278 // Either |write_failure| specifies a write failure or |read_failure|
279 // specifies a read failure when using a reused socket. In either case, the
280 // failure should cause the network transaction to resend the request, and the
281 // other argument should be NULL.
282 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
283 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52284
[email protected]5a60c8b2011-10-19 20:14:29285 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
286 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15287 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52288
[email protected]ff007e162009-05-23 09:13:15289 HttpRequestInfo request;
290 request.method = "GET";
291 request.url = GURL("http://www.google.com/");
292 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52293
[email protected]58e32bb2013-01-21 18:23:25294 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07295 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07296 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27297 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07298 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27299
[email protected]5a60c8b2011-10-19 20:14:29300 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07301 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29302 }
initial.commit586acc5fe2008-07-26 22:42:52303
[email protected]49639fa2011-12-20 23:22:41304 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52305
[email protected]c47c0372014-03-12 23:07:02306 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41307 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15308 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52309
[email protected]ff007e162009-05-23 09:13:15310 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25311
312 // Even in the failure cases that use this function, connections are always
313 // successfully established before the error.
314 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
315 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
316
[email protected]ff007e162009-05-23 09:13:15317 if (out.rv != OK)
318 return out;
319
320 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50321 // Can't use ASSERT_* inside helper functions like this, so
322 // return an error.
[email protected]90499482013-06-01 00:39:50323 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50324 out.rv = ERR_UNEXPECTED;
325 return out;
326 }
[email protected]ff007e162009-05-23 09:13:15327 out.status_line = response->headers->GetStatusLine();
328
[email protected]80a09a82012-11-16 17:40:06329 EXPECT_EQ("127.0.0.1", response->socket_address.host());
330 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19331
[email protected]ff007e162009-05-23 09:13:15332 rv = ReadTransaction(trans.get(), &out.response_data);
333 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40334
[email protected]f3da152d2012-06-02 01:00:57335 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40336 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39337 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40338 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12339 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39340 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40341 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39342 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
343 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15344
[email protected]f3da152d2012-06-02 01:00:57345 std::string line;
346 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
347 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
348
[email protected]79e1fd62013-06-20 06:50:04349 HttpRequestHeaders request_headers;
350 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
351 std::string value;
352 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
353 EXPECT_EQ("www.google.com", value);
354 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
355 EXPECT_EQ("keep-alive", value);
356
357 std::string response_headers;
358 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
359 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
360 response_headers);
[email protected]3deb9a52010-11-11 00:24:40361
[email protected]b8015c42013-12-24 15:18:19362 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47363 return out;
[email protected]ff007e162009-05-23 09:13:15364 }
initial.commit586acc5fe2008-07-26 22:42:52365
[email protected]5a60c8b2011-10-19 20:14:29366 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
367 size_t reads_count) {
368 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
369 StaticSocketDataProvider* data[] = { &reads };
370 return SimpleGetHelperForData(data, 1);
371 }
372
[email protected]b8015c42013-12-24 15:18:19373 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
374 int64 size = 0;
375 for (size_t i = 0; i < reads_count; ++i)
376 size += data_reads[i].data_len;
377 return size;
378 }
379
[email protected]ff007e162009-05-23 09:13:15380 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
381 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52382
[email protected]ff007e162009-05-23 09:13:15383 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07384
385 void BypassHostCacheOnRefreshHelper(int load_flags);
386
387 void CheckErrorIsPassedBack(int error, IoMode mode);
388
[email protected]4bd46222013-05-14 19:32:23389 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07390 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03391
392 // Original socket limits. Some tests set these. Safest to always restore
393 // them once each test has been run.
394 int old_max_group_sockets_;
395 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15396};
[email protected]231d5a32008-09-13 00:45:27397
[email protected]23e482282013-06-14 16:08:02398INSTANTIATE_TEST_CASE_P(
399 NextProto,
400 HttpNetworkTransactionTest,
[email protected]b05bcaa32013-10-06 05:26:02401 testing::Values(kProtoDeprecatedSPDY2,
402 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
[email protected]88a332622013-07-30 07:13:32403 kProtoHTTP2Draft04));
[email protected]23e482282013-06-14 16:08:02404
[email protected]448d4ca52012-03-04 04:12:23405namespace {
406
[email protected]1826a402014-01-08 15:40:48407class BeforeNetworkStartHandler {
408 public:
409 explicit BeforeNetworkStartHandler(bool defer)
410 : defer_on_before_network_start_(defer),
411 observed_before_network_start_(false) {}
412
413 void OnBeforeNetworkStart(bool* defer) {
414 *defer = defer_on_before_network_start_;
415 observed_before_network_start_ = true;
416 }
417
418 bool observed_before_network_start() const {
419 return observed_before_network_start_;
420 }
421
422 private:
423 const bool defer_on_before_network_start_;
424 bool observed_before_network_start_;
425
426 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
427};
428
[email protected]15a5ccf82008-10-23 19:57:43429// Fill |str| with a long header list that consumes >= |size| bytes.
430void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19431 const char* row =
432 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
433 const int sizeof_row = strlen(row);
434 const int num_rows = static_cast<int>(
435 ceil(static_cast<float>(size) / sizeof_row));
436 const int sizeof_data = num_rows * sizeof_row;
437 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43438 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51439
[email protected]4ddaf2502008-10-23 18:26:19440 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43441 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19442}
443
[email protected]385a4672009-03-11 22:21:29444// Alternative functions that eliminate randomness and dependency on the local
445// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20446void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29447 static const uint8 bytes[] = {
448 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
449 };
450 static size_t current_byte = 0;
451 for (size_t i = 0; i < n; ++i) {
452 output[i] = bytes[current_byte++];
453 current_byte %= arraysize(bytes);
454 }
455}
456
[email protected]fe2bc6a2009-03-23 16:52:20457void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29458 static const uint8 bytes[] = {
459 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
460 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
461 };
462 static size_t current_byte = 0;
463 for (size_t i = 0; i < n; ++i) {
464 output[i] = bytes[current_byte++];
465 current_byte %= arraysize(bytes);
466 }
467}
468
[email protected]fe2bc6a2009-03-23 16:52:20469std::string MockGetHostName() {
470 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29471}
472
[email protected]e60e47a2010-07-14 03:37:18473template<typename ParentPool>
474class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31475 public:
[email protected]9e1bdd32011-02-03 21:48:34476 CaptureGroupNameSocketPool(HostResolver* host_resolver,
477 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18478
[email protected]d80a4322009-08-14 07:07:49479 const std::string last_group_name_received() const {
480 return last_group_name_;
481 }
482
[email protected]684970b2009-08-14 04:54:46483 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49484 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31485 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31486 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41487 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53488 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31489 last_group_name_ = group_name;
490 return ERR_IO_PENDING;
491 }
[email protected]04e5be32009-06-26 20:00:31492 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21493 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31494 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44495 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19496 int id) {}
[email protected]04e5be32009-06-26 20:00:31497 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31498 virtual int IdleSocketCount() const {
499 return 0;
500 }
501 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
502 return 0;
503 }
504 virtual LoadState GetLoadState(const std::string& group_name,
505 const ClientSocketHandle* handle) const {
506 return LOAD_STATE_IDLE;
507 }
[email protected]a796bcec2010-03-22 17:17:26508 virtual base::TimeDelta ConnectionTimeout() const {
509 return base::TimeDelta();
510 }
[email protected]d80a4322009-08-14 07:07:49511
512 private:
[email protected]04e5be32009-06-26 20:00:31513 std::string last_group_name_;
514};
515
[email protected]ab739042011-04-07 15:22:28516typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
517CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13518typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
519CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06520typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11521CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18522typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
523CaptureGroupNameSSLSocketPool;
524
525template<typename ParentPool>
526CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34527 HostResolver* host_resolver,
528 CertVerifier* /* cert_verifier */)
529 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18530
531template<>
[email protected]2df19bb2010-08-25 20:13:46532CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34533 HostResolver* host_resolver,
534 CertVerifier* /* cert_verifier */)
535 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46536
[email protected]007b3f82013-04-09 08:46:45537template <>
[email protected]e60e47a2010-07-14 03:37:18538CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34539 HostResolver* host_resolver,
540 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45541 : SSLClientSocketPool(0,
542 0,
543 NULL,
544 host_resolver,
545 cert_verifier,
546 NULL,
547 NULL,
[email protected]284303b62013-11-28 15:11:54548 NULL,
[email protected]007b3f82013-04-09 08:46:45549 std::string(),
550 NULL,
551 NULL,
552 NULL,
553 NULL,
554 NULL,
555 NULL) {}
[email protected]2227c692010-05-04 15:36:11556
[email protected]231d5a32008-09-13 00:45:27557//-----------------------------------------------------------------------------
558
[email protected]79cb5c12011-09-12 13:12:04559// Helper functions for validating that AuthChallengeInfo's are correctly
560// configured for common cases.
561bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
562 if (!auth_challenge)
563 return false;
564 EXPECT_FALSE(auth_challenge->is_proxy);
565 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
566 EXPECT_EQ("MyRealm1", auth_challenge->realm);
567 EXPECT_EQ("basic", auth_challenge->scheme);
568 return true;
569}
570
571bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
572 if (!auth_challenge)
573 return false;
574 EXPECT_TRUE(auth_challenge->is_proxy);
575 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
576 EXPECT_EQ("MyRealm1", auth_challenge->realm);
577 EXPECT_EQ("basic", auth_challenge->scheme);
578 return true;
579}
580
581bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
582 if (!auth_challenge)
583 return false;
584 EXPECT_FALSE(auth_challenge->is_proxy);
585 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
586 EXPECT_EQ("digestive", auth_challenge->realm);
587 EXPECT_EQ("digest", auth_challenge->scheme);
588 return true;
589}
590
591bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
592 if (!auth_challenge)
593 return false;
594 EXPECT_FALSE(auth_challenge->is_proxy);
595 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
596 EXPECT_EQ(std::string(), auth_challenge->realm);
597 EXPECT_EQ("ntlm", auth_challenge->scheme);
598 return true;
599}
600
[email protected]448d4ca52012-03-04 04:12:23601} // namespace
602
[email protected]23e482282013-06-14 16:08:02603TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07604 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40605 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]231d5a32008-09-13 00:45:27607}
608
[email protected]23e482282013-06-14 16:08:02609TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27610 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35611 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
612 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06613 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27614 };
[email protected]31a2bfe2010-02-09 08:03:39615 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
616 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42617 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27618 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
619 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19620 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
621 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27622}
623
624// Response with no status line.
[email protected]23e482282013-06-14 16:08:02625TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27626 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35627 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06628 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27629 };
[email protected]31a2bfe2010-02-09 08:03:39630 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
631 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42632 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27633 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
634 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19635 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
636 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27637}
638
639// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02640TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27641 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35642 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06643 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27644 };
[email protected]31a2bfe2010-02-09 08:03:39645 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
646 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42647 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27648 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
649 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19650 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
651 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27652}
653
654// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02655TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27656 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35657 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06658 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27659 };
[email protected]31a2bfe2010-02-09 08:03:39660 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
661 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42662 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27663 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
664 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19665 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
666 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27667}
668
669// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02670TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27671 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35672 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06673 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27674 };
[email protected]31a2bfe2010-02-09 08:03:39675 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
676 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42677 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25678 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
679 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19680 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
681 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27682}
683
684// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02685TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27686 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35687 MockRead("\n"),
688 MockRead("\n"),
689 MockRead("Q"),
690 MockRead("J"),
691 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06692 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27693 };
[email protected]31a2bfe2010-02-09 08:03:39694 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
695 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42696 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27697 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
698 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19699 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
700 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27701}
702
703// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02704TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27705 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35706 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06707 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27708 };
[email protected]31a2bfe2010-02-09 08:03:39709 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
710 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42711 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27712 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
713 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19714 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
715 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52716}
717
[email protected]f9d44aa2008-09-23 23:57:17718// Simulate a 204 response, lacking a Content-Length header, sent over a
719// persistent connection. The response should still terminate since a 204
720// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02721TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19722 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17723 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35724 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19725 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06726 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17727 };
[email protected]31a2bfe2010-02-09 08:03:39728 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
729 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42730 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17731 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
732 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19733 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
734 int64 response_size = reads_size - strlen(junk);
735 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17736}
737
[email protected]0877e3d2009-10-17 22:29:57738// A simple request using chunked encoding with some extra data after.
739// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02740TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19741 std::string final_chunk = "0\r\n\r\n";
742 std::string extra_data = "HTTP/1.1 200 OK\r\n";
743 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57744 MockRead data_reads[] = {
745 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
746 MockRead("5\r\nHello\r\n"),
747 MockRead("1\r\n"),
748 MockRead(" \r\n"),
749 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19750 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06751 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57752 };
[email protected]31a2bfe2010-02-09 08:03:39753 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
754 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57755 EXPECT_EQ(OK, out.rv);
756 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
757 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19758 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
759 int64 response_size = reads_size - extra_data.size();
760 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57761}
762
[email protected]9fe44f52010-09-23 18:36:00763// Next tests deal with http://crbug.com/56344.
764
[email protected]23e482282013-06-14 16:08:02765TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00766 MultipleContentLengthHeadersNoTransferEncoding) {
767 MockRead data_reads[] = {
768 MockRead("HTTP/1.1 200 OK\r\n"),
769 MockRead("Content-Length: 10\r\n"),
770 MockRead("Content-Length: 5\r\n\r\n"),
771 };
772 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
773 arraysize(data_reads));
774 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
775}
776
[email protected]23e482282013-06-14 16:08:02777TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04778 DuplicateContentLengthHeadersNoTransferEncoding) {
779 MockRead data_reads[] = {
780 MockRead("HTTP/1.1 200 OK\r\n"),
781 MockRead("Content-Length: 5\r\n"),
782 MockRead("Content-Length: 5\r\n\r\n"),
783 MockRead("Hello"),
784 };
785 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
786 arraysize(data_reads));
787 EXPECT_EQ(OK, out.rv);
788 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
789 EXPECT_EQ("Hello", out.response_data);
790}
791
[email protected]23e482282013-06-14 16:08:02792TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04793 ComplexContentLengthHeadersNoTransferEncoding) {
794 // More than 2 dupes.
795 {
796 MockRead data_reads[] = {
797 MockRead("HTTP/1.1 200 OK\r\n"),
798 MockRead("Content-Length: 5\r\n"),
799 MockRead("Content-Length: 5\r\n"),
800 MockRead("Content-Length: 5\r\n\r\n"),
801 MockRead("Hello"),
802 };
803 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
804 arraysize(data_reads));
805 EXPECT_EQ(OK, out.rv);
806 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
807 EXPECT_EQ("Hello", out.response_data);
808 }
809 // HTTP/1.0
810 {
811 MockRead data_reads[] = {
812 MockRead("HTTP/1.0 200 OK\r\n"),
813 MockRead("Content-Length: 5\r\n"),
814 MockRead("Content-Length: 5\r\n"),
815 MockRead("Content-Length: 5\r\n\r\n"),
816 MockRead("Hello"),
817 };
818 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
819 arraysize(data_reads));
820 EXPECT_EQ(OK, out.rv);
821 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
822 EXPECT_EQ("Hello", out.response_data);
823 }
824 // 2 dupes and one mismatched.
825 {
826 MockRead data_reads[] = {
827 MockRead("HTTP/1.1 200 OK\r\n"),
828 MockRead("Content-Length: 10\r\n"),
829 MockRead("Content-Length: 10\r\n"),
830 MockRead("Content-Length: 5\r\n\r\n"),
831 };
832 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
833 arraysize(data_reads));
834 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
835 }
836}
837
[email protected]23e482282013-06-14 16:08:02838TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00839 MultipleContentLengthHeadersTransferEncoding) {
840 MockRead data_reads[] = {
841 MockRead("HTTP/1.1 200 OK\r\n"),
842 MockRead("Content-Length: 666\r\n"),
843 MockRead("Content-Length: 1337\r\n"),
844 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
845 MockRead("5\r\nHello\r\n"),
846 MockRead("1\r\n"),
847 MockRead(" \r\n"),
848 MockRead("5\r\nworld\r\n"),
849 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06850 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00851 };
852 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
853 arraysize(data_reads));
854 EXPECT_EQ(OK, out.rv);
855 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
856 EXPECT_EQ("Hello world", out.response_data);
857}
858
[email protected]1628fe92011-10-04 23:04:55859// Next tests deal with http://crbug.com/98895.
860
861// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02862TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55863 MockRead data_reads[] = {
864 MockRead("HTTP/1.1 200 OK\r\n"),
865 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
866 MockRead("Content-Length: 5\r\n\r\n"),
867 MockRead("Hello"),
868 };
869 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
870 arraysize(data_reads));
871 EXPECT_EQ(OK, out.rv);
872 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
873 EXPECT_EQ("Hello", out.response_data);
874}
875
[email protected]54a9c6e52012-03-21 20:10:59876// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02877TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59878 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55879 MockRead data_reads[] = {
880 MockRead("HTTP/1.1 200 OK\r\n"),
881 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
882 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
883 MockRead("Content-Length: 5\r\n\r\n"),
884 MockRead("Hello"),
885 };
886 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
887 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59888 EXPECT_EQ(OK, out.rv);
889 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
890 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55891}
892
893// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02894TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55895 MockRead data_reads[] = {
896 MockRead("HTTP/1.1 200 OK\r\n"),
897 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
898 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
899 MockRead("Content-Length: 5\r\n\r\n"),
900 MockRead("Hello"),
901 };
902 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
903 arraysize(data_reads));
904 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
905}
906
[email protected]54a9c6e52012-03-21 20:10:59907// Checks that two identical Location headers result in no error.
908// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02909TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55910 MockRead data_reads[] = {
911 MockRead("HTTP/1.1 302 Redirect\r\n"),
912 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59913 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55914 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06915 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55916 };
917
918 HttpRequestInfo request;
919 request.method = "GET";
920 request.url = GURL("http://redirect.com/");
921 request.load_flags = 0;
922
[email protected]3fe8d2f82013-10-17 08:56:07923 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55924 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07925 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]1628fe92011-10-04 23:04:55926
927 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07928 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55929
[email protected]49639fa2011-12-20 23:22:41930 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55931
[email protected]49639fa2011-12-20 23:22:41932 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55933 EXPECT_EQ(ERR_IO_PENDING, rv);
934
935 EXPECT_EQ(OK, callback.WaitForResult());
936
937 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50938 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55939 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
940 std::string url;
941 EXPECT_TRUE(response->headers->IsRedirect(&url));
942 EXPECT_EQ("http://good.com/", url);
943}
944
[email protected]1628fe92011-10-04 23:04:55945// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02946TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55947 MockRead data_reads[] = {
948 MockRead("HTTP/1.1 302 Redirect\r\n"),
949 MockRead("Location: http://good.com/\r\n"),
950 MockRead("Location: http://evil.com/\r\n"),
951 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06952 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55953 };
954 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
955 arraysize(data_reads));
956 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
957}
958
[email protected]ef0faf2e72009-03-05 23:27:23959// Do a request using the HEAD method. Verify that we don't try to read the
960// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02961TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42962 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23963 request.method = "HEAD";
964 request.url = GURL("http://www.google.com/");
965 request.load_flags = 0;
966
[email protected]3fe8d2f82013-10-17 08:56:07967 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27968 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:07969 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:27970
[email protected]ef0faf2e72009-03-05 23:27:23971 MockWrite data_writes1[] = {
972 MockWrite("HEAD / HTTP/1.1\r\n"
973 "Host: www.google.com\r\n"
974 "Connection: keep-alive\r\n"
975 "Content-Length: 0\r\n\r\n"),
976 };
977 MockRead data_reads1[] = {
978 MockRead("HTTP/1.1 404 Not Found\r\n"),
979 MockRead("Server: Blah\r\n"),
980 MockRead("Content-Length: 1234\r\n\r\n"),
981
982 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06983 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23984 };
985
[email protected]31a2bfe2010-02-09 08:03:39986 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
987 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23989
[email protected]49639fa2011-12-20 23:22:41990 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23991
[email protected]49639fa2011-12-20 23:22:41992 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42993 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23994
995 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42996 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23997
[email protected]1c773ea12009-04-28 19:58:42998 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50999 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231000
1001 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501002 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231003 EXPECT_EQ(1234, response->headers->GetContentLength());
1004 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1005
1006 std::string server_header;
1007 void* iter = NULL;
1008 bool has_server_header = response->headers->EnumerateHeader(
1009 &iter, "Server", &server_header);
1010 EXPECT_TRUE(has_server_header);
1011 EXPECT_EQ("Blah", server_header);
1012
1013 // Reading should give EOF right away, since there is no message body
1014 // (despite non-zero content-length).
1015 std::string response_data;
1016 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421017 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231018 EXPECT_EQ("", response_data);
1019}
1020
[email protected]23e482282013-06-14 16:08:021021TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071022 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521023
1024 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351025 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1026 MockRead("hello"),
1027 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1028 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061029 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521030 };
[email protected]31a2bfe2010-02-09 08:03:391031 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071032 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521033
[email protected]0b0bf032010-09-21 18:08:501034 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521035 "hello", "world"
1036 };
1037
1038 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421039 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521040 request.method = "GET";
1041 request.url = GURL("http://www.google.com/");
1042 request.load_flags = 0;
1043
[email protected]262eec82013-03-19 21:01:361044 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501045 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271046
[email protected]49639fa2011-12-20 23:22:411047 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521048
[email protected]49639fa2011-12-20 23:22:411049 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421050 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521051
1052 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421053 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521054
[email protected]1c773ea12009-04-28 19:58:421055 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501056 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521057
[email protected]90499482013-06-01 00:39:501058 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251059 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521060
1061 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571062 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421063 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251064 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521065 }
1066}
1067
[email protected]23e482282013-06-14 16:08:021068TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061069 ScopedVector<UploadElementReader> element_readers;
1070 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:201071 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271072
[email protected]1c773ea12009-04-28 19:58:421073 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521074 request.method = "POST";
1075 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271076 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521077 request.load_flags = 0;
1078
[email protected]3fe8d2f82013-10-17 08:56:071079 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271080 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271082
initial.commit586acc5fe2008-07-26 22:42:521083 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351084 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1085 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1086 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061087 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521088 };
[email protected]31a2bfe2010-02-09 08:03:391089 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071090 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521091
[email protected]49639fa2011-12-20 23:22:411092 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521093
[email protected]49639fa2011-12-20 23:22:411094 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421095 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521096
1097 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421098 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521099
[email protected]1c773ea12009-04-28 19:58:421100 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501101 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521102
[email protected]90499482013-06-01 00:39:501103 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251104 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521105
1106 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571107 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421108 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251109 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521110}
1111
[email protected]3a2d3662009-03-27 03:49:141112// This test is almost the same as Ignores100 above, but the response contains
1113// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571114// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021115TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421116 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141117 request.method = "GET";
1118 request.url = GURL("http://www.foo.com/");
1119 request.load_flags = 0;
1120
[email protected]3fe8d2f82013-10-17 08:56:071121 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271122 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071123 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271124
[email protected]3a2d3662009-03-27 03:49:141125 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571126 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1127 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141128 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061129 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141130 };
[email protected]31a2bfe2010-02-09 08:03:391131 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071132 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141133
[email protected]49639fa2011-12-20 23:22:411134 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141135
[email protected]49639fa2011-12-20 23:22:411136 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421137 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141138
1139 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421140 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141141
[email protected]1c773ea12009-04-28 19:58:421142 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501143 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141144
[email protected]90499482013-06-01 00:39:501145 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141146 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1147
1148 std::string response_data;
1149 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421150 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141151 EXPECT_EQ("hello world", response_data);
1152}
1153
[email protected]23e482282013-06-14 16:08:021154TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381155 HttpRequestInfo request;
1156 request.method = "POST";
1157 request.url = GURL("http://www.foo.com/");
1158 request.load_flags = 0;
1159
[email protected]3fe8d2f82013-10-17 08:56:071160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271161 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071162 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271163
[email protected]ee9410e72010-01-07 01:42:381164 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061165 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1166 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381167 };
[email protected]31a2bfe2010-02-09 08:03:391168 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071169 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381170
[email protected]49639fa2011-12-20 23:22:411171 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381172
[email protected]49639fa2011-12-20 23:22:411173 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381174 EXPECT_EQ(ERR_IO_PENDING, rv);
1175
1176 rv = callback.WaitForResult();
1177 EXPECT_EQ(OK, rv);
1178
1179 std::string response_data;
1180 rv = ReadTransaction(trans.get(), &response_data);
1181 EXPECT_EQ(OK, rv);
1182 EXPECT_EQ("", response_data);
1183}
1184
[email protected]23e482282013-06-14 16:08:021185TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381186 HttpRequestInfo request;
1187 request.method = "POST";
1188 request.url = GURL("http://www.foo.com/");
1189 request.load_flags = 0;
1190
[email protected]3fe8d2f82013-10-17 08:56:071191 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271192 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1194
[email protected]cb9bf6ca2011-01-28 13:15:271195
[email protected]ee9410e72010-01-07 01:42:381196 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061197 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381198 };
[email protected]31a2bfe2010-02-09 08:03:391199 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071200 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381201
[email protected]49639fa2011-12-20 23:22:411202 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381203
[email protected]49639fa2011-12-20 23:22:411204 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381205 EXPECT_EQ(ERR_IO_PENDING, rv);
1206
1207 rv = callback.WaitForResult();
1208 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1209}
1210
[email protected]23e482282013-06-14 16:08:021211void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511212 const MockWrite* write_failure,
1213 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421214 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521215 request.method = "GET";
1216 request.url = GURL("http://www.foo.com/");
1217 request.load_flags = 0;
1218
[email protected]58e32bb2013-01-21 18:23:251219 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071220 session_deps_.net_log = &net_log;
1221 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271222
[email protected]202965992011-12-07 23:04:511223 // Written data for successfully sending both requests.
1224 MockWrite data1_writes[] = {
1225 MockWrite("GET / HTTP/1.1\r\n"
1226 "Host: www.foo.com\r\n"
1227 "Connection: keep-alive\r\n\r\n"),
1228 MockWrite("GET / HTTP/1.1\r\n"
1229 "Host: www.foo.com\r\n"
1230 "Connection: keep-alive\r\n\r\n")
1231 };
1232
1233 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521234 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351235 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1236 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061237 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521238 };
[email protected]202965992011-12-07 23:04:511239
1240 if (write_failure) {
1241 ASSERT_TRUE(!read_failure);
1242 data1_writes[1] = *write_failure;
1243 } else {
1244 ASSERT_TRUE(read_failure);
1245 data1_reads[2] = *read_failure;
1246 }
1247
1248 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1249 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071250 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521251
1252 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351253 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1254 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061255 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521256 };
[email protected]31a2bfe2010-02-09 08:03:391257 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071258 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521259
1260 const char* kExpectedResponseData[] = {
1261 "hello", "world"
1262 };
1263
[email protected]58e32bb2013-01-21 18:23:251264 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521265 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411266 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521267
[email protected]262eec82013-03-19 21:01:361268 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521270
[email protected]49639fa2011-12-20 23:22:411271 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421272 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521273
1274 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421275 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521276
[email protected]58e32bb2013-01-21 18:23:251277 LoadTimingInfo load_timing_info;
1278 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1279 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1280 if (i == 0) {
1281 first_socket_log_id = load_timing_info.socket_log_id;
1282 } else {
1283 // The second request should be using a new socket.
1284 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1285 }
1286
[email protected]1c773ea12009-04-28 19:58:421287 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501288 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521289
[email protected]90499482013-06-01 00:39:501290 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251291 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521292
1293 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571294 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421295 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251296 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521297 }
1298}
[email protected]3d2a59b2008-09-26 19:44:251299
[email protected]23e482282013-06-14 16:08:021300TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231301 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061302 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511303 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1304}
1305
[email protected]23e482282013-06-14 16:08:021306TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061307 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511308 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251309}
1310
[email protected]23e482282013-06-14 16:08:021311TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061312 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511313 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251314}
1315
[email protected]23e482282013-06-14 16:08:021316TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421317 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251318 request.method = "GET";
1319 request.url = GURL("http://www.google.com/");
1320 request.load_flags = 0;
1321
[email protected]3fe8d2f82013-10-17 08:56:071322 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271323 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071324 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271325
[email protected]3d2a59b2008-09-26 19:44:251326 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061327 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351328 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1329 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061330 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251331 };
[email protected]31a2bfe2010-02-09 08:03:391332 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071333 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251334
[email protected]49639fa2011-12-20 23:22:411335 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251336
[email protected]49639fa2011-12-20 23:22:411337 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421338 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251339
1340 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421341 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251342
[email protected]1c773ea12009-04-28 19:58:421343 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251344 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251345}
1346
1347// What do various browsers do when the server closes a non-keepalive
1348// connection without sending any response header or body?
1349//
1350// IE7: error page
1351// Safari 3.1.2 (Windows): error page
1352// Firefox 3.0.1: blank page
1353// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421354// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1355// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021356TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251357 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061358 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351359 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1360 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061361 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251362 };
[email protected]31a2bfe2010-02-09 08:03:391363 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1364 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421365 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251366}
[email protected]038e9a32008-10-08 22:40:161367
[email protected]1826a402014-01-08 15:40:481368// Test that network access can be deferred and resumed.
1369TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1370 HttpRequestInfo request;
1371 request.method = "GET";
1372 request.url = GURL("http://www.google.com/");
1373 request.load_flags = 0;
1374
1375 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1376 scoped_ptr<HttpTransaction> trans(
1377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1378
1379 // Defer on OnBeforeNetworkStart.
1380 BeforeNetworkStartHandler net_start_handler(true); // defer
1381 trans->SetBeforeNetworkStartCallback(
1382 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1383 base::Unretained(&net_start_handler)));
1384
1385 MockRead data_reads[] = {
1386 MockRead("HTTP/1.0 200 OK\r\n"),
1387 MockRead("Content-Length: 5\r\n\r\n"),
1388 MockRead("hello"),
1389 MockRead(SYNCHRONOUS, 0),
1390 };
1391 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1392 session_deps_.socket_factory->AddSocketDataProvider(&data);
1393
1394 TestCompletionCallback callback;
1395
1396 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1397 EXPECT_EQ(ERR_IO_PENDING, rv);
1398 base::MessageLoop::current()->RunUntilIdle();
1399
1400 // Should have deferred for network start.
1401 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1402 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1403 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1404
1405 trans->ResumeNetworkStart();
1406 rv = callback.WaitForResult();
1407 EXPECT_EQ(OK, rv);
1408 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1409
1410 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1411 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1412 if (rv == ERR_IO_PENDING)
1413 rv = callback.WaitForResult();
1414 EXPECT_EQ(5, rv);
1415 trans.reset();
1416}
1417
1418// Test that network use can be deferred and canceled.
1419TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1420 HttpRequestInfo request;
1421 request.method = "GET";
1422 request.url = GURL("http://www.google.com/");
1423 request.load_flags = 0;
1424
1425 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1426 scoped_ptr<HttpTransaction> trans(
1427 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1428
1429 // Defer on OnBeforeNetworkStart.
1430 BeforeNetworkStartHandler net_start_handler(true); // defer
1431 trans->SetBeforeNetworkStartCallback(
1432 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1433 base::Unretained(&net_start_handler)));
1434
1435 TestCompletionCallback callback;
1436
1437 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1438 EXPECT_EQ(ERR_IO_PENDING, rv);
1439 base::MessageLoop::current()->RunUntilIdle();
1440
1441 // Should have deferred for network start.
1442 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1443 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1444 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1445}
1446
[email protected]7a5378b2012-11-04 03:25:171447// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1448// tests. There was a bug causing HttpNetworkTransaction to hang in the
1449// destructor in such situations.
1450// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021451TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171452 HttpRequestInfo request;
1453 request.method = "GET";
1454 request.url = GURL("http://www.google.com/");
1455 request.load_flags = 0;
1456
[email protected]bb88e1d32013-05-03 23:11:071457 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361458 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171460
1461 MockRead data_reads[] = {
1462 MockRead("HTTP/1.0 200 OK\r\n"),
1463 MockRead("Connection: keep-alive\r\n"),
1464 MockRead("Content-Length: 100\r\n\r\n"),
1465 MockRead("hello"),
1466 MockRead(SYNCHRONOUS, 0),
1467 };
1468 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071469 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171470
1471 TestCompletionCallback callback;
1472
1473 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1474 EXPECT_EQ(ERR_IO_PENDING, rv);
1475
1476 rv = callback.WaitForResult();
1477 EXPECT_EQ(OK, rv);
1478
1479 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501480 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171481 if (rv == ERR_IO_PENDING)
1482 rv = callback.WaitForResult();
1483 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501484 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171485 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1486
1487 trans.reset();
[email protected]2da659e2013-05-23 20:51:341488 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171489 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1490}
1491
[email protected]23e482282013-06-14 16:08:021492TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171493 HttpRequestInfo request;
1494 request.method = "GET";
1495 request.url = GURL("http://www.google.com/");
1496 request.load_flags = 0;
1497
[email protected]bb88e1d32013-05-03 23:11:071498 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361499 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501500 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171501
1502 MockRead data_reads[] = {
1503 MockRead("HTTP/1.0 200 OK\r\n"),
1504 MockRead("Connection: keep-alive\r\n"),
1505 MockRead("Content-Length: 100\r\n\r\n"),
1506 MockRead(SYNCHRONOUS, 0),
1507 };
1508 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071509 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171510
1511 TestCompletionCallback callback;
1512
1513 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1514 EXPECT_EQ(ERR_IO_PENDING, rv);
1515
1516 rv = callback.WaitForResult();
1517 EXPECT_EQ(OK, rv);
1518
1519 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501520 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171521 if (rv == ERR_IO_PENDING)
1522 rv = callback.WaitForResult();
1523 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1524
1525 trans.reset();
[email protected]2da659e2013-05-23 20:51:341526 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171527 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1528}
1529
[email protected]0b0bf032010-09-21 18:08:501530// Test that we correctly reuse a keep-alive connection after not explicitly
1531// reading the body.
[email protected]23e482282013-06-14 16:08:021532TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131533 HttpRequestInfo request;
1534 request.method = "GET";
1535 request.url = GURL("http://www.foo.com/");
1536 request.load_flags = 0;
1537
[email protected]58e32bb2013-01-21 18:23:251538 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071539 session_deps_.net_log = &net_log;
1540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271541
[email protected]0b0bf032010-09-21 18:08:501542 // Note that because all these reads happen in the same
1543 // StaticSocketDataProvider, it shows that the same socket is being reused for
1544 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131545 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501546 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1547 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131548 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501549 MockRead("HTTP/1.1 302 Found\r\n"
1550 "Content-Length: 0\r\n\r\n"),
1551 MockRead("HTTP/1.1 302 Found\r\n"
1552 "Content-Length: 5\r\n\r\n"
1553 "hello"),
1554 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1555 "Content-Length: 0\r\n\r\n"),
1556 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1557 "Content-Length: 5\r\n\r\n"
1558 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131559 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1560 MockRead("hello"),
1561 };
1562 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071563 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131564
1565 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061566 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131567 };
1568 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071569 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131570
[email protected]0b0bf032010-09-21 18:08:501571 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1572 std::string response_lines[kNumUnreadBodies];
1573
[email protected]58e32bb2013-01-21 18:23:251574 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501575 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411576 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131577
[email protected]262eec82013-03-19 21:01:361578 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501579 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131580
[email protected]49639fa2011-12-20 23:22:411581 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131582 EXPECT_EQ(ERR_IO_PENDING, rv);
1583
1584 rv = callback.WaitForResult();
1585 EXPECT_EQ(OK, rv);
1586
[email protected]58e32bb2013-01-21 18:23:251587 LoadTimingInfo load_timing_info;
1588 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1589 if (i == 0) {
1590 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1591 first_socket_log_id = load_timing_info.socket_log_id;
1592 } else {
1593 TestLoadTimingReused(load_timing_info);
1594 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1595 }
1596
[email protected]fc31d6a42010-06-24 18:05:131597 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501598 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131599
[email protected]90499482013-06-01 00:39:501600 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501601 response_lines[i] = response->headers->GetStatusLine();
1602
1603 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131604 }
[email protected]0b0bf032010-09-21 18:08:501605
1606 const char* const kStatusLines[] = {
1607 "HTTP/1.1 204 No Content",
1608 "HTTP/1.1 205 Reset Content",
1609 "HTTP/1.1 304 Not Modified",
1610 "HTTP/1.1 302 Found",
1611 "HTTP/1.1 302 Found",
1612 "HTTP/1.1 301 Moved Permanently",
1613 "HTTP/1.1 301 Moved Permanently",
1614 };
1615
1616 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1617 forgot_to_update_kStatusLines);
1618
1619 for (int i = 0; i < kNumUnreadBodies; ++i)
1620 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1621
[email protected]49639fa2011-12-20 23:22:411622 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361623 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501624 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411625 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501626 EXPECT_EQ(ERR_IO_PENDING, rv);
1627 rv = callback.WaitForResult();
1628 EXPECT_EQ(OK, rv);
1629 const HttpResponseInfo* response = trans->GetResponseInfo();
1630 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501631 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501632 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1633 std::string response_data;
1634 rv = ReadTransaction(trans.get(), &response_data);
1635 EXPECT_EQ(OK, rv);
1636 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131637}
1638
[email protected]038e9a32008-10-08 22:40:161639// Test the request-challenge-retry sequence for basic auth.
1640// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021641TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421642 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161643 request.method = "GET";
1644 request.url = GURL("http://www.google.com/");
1645 request.load_flags = 0;
1646
[email protected]58e32bb2013-01-21 18:23:251647 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071648 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071649 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271650 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071651 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271652
[email protected]f9ee6b52008-11-08 06:46:231653 MockWrite data_writes1[] = {
1654 MockWrite("GET / HTTP/1.1\r\n"
1655 "Host: www.google.com\r\n"
1656 "Connection: keep-alive\r\n\r\n"),
1657 };
1658
[email protected]038e9a32008-10-08 22:40:161659 MockRead data_reads1[] = {
1660 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1661 // Give a couple authenticate options (only the middle one is actually
1662 // supported).
[email protected]22927ad2009-09-21 19:56:191663 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161664 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1665 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1666 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1667 // Large content-length -- won't matter, as connection will be reset.
1668 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061669 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161670 };
1671
1672 // After calling trans->RestartWithAuth(), this is the request we should
1673 // be issuing -- the final header line contains the credentials.
1674 MockWrite data_writes2[] = {
1675 MockWrite("GET / HTTP/1.1\r\n"
1676 "Host: www.google.com\r\n"
1677 "Connection: keep-alive\r\n"
1678 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1679 };
1680
1681 // Lastly, the server responds with the actual content.
1682 MockRead data_reads2[] = {
1683 MockRead("HTTP/1.0 200 OK\r\n"),
1684 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1685 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061686 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161687 };
1688
[email protected]31a2bfe2010-02-09 08:03:391689 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1690 data_writes1, arraysize(data_writes1));
1691 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1692 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071693 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1694 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161695
[email protected]49639fa2011-12-20 23:22:411696 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161697
[email protected]49639fa2011-12-20 23:22:411698 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421699 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161700
1701 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421702 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161703
[email protected]58e32bb2013-01-21 18:23:251704 LoadTimingInfo load_timing_info1;
1705 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1706 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1707
[email protected]b8015c42013-12-24 15:18:191708 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1709 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1710
[email protected]1c773ea12009-04-28 19:58:421711 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501712 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041713 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161714
[email protected]49639fa2011-12-20 23:22:411715 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161716
[email protected]49639fa2011-12-20 23:22:411717 rv = trans->RestartWithAuth(
1718 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421719 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161720
1721 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421722 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161723
[email protected]58e32bb2013-01-21 18:23:251724 LoadTimingInfo load_timing_info2;
1725 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1726 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1727 // The load timing after restart should have a new socket ID, and times after
1728 // those of the first load timing.
1729 EXPECT_LE(load_timing_info1.receive_headers_end,
1730 load_timing_info2.connect_timing.connect_start);
1731 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1732
[email protected]b8015c42013-12-24 15:18:191733 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1734 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1735
[email protected]038e9a32008-10-08 22:40:161736 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501737 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161738 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1739 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161740}
1741
[email protected]23e482282013-06-14 16:08:021742TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461743 HttpRequestInfo request;
1744 request.method = "GET";
1745 request.url = GURL("http://www.google.com/");
1746 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1747
[email protected]3fe8d2f82013-10-17 08:56:071748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271749 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:071750 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:271751
[email protected]861fcd52009-08-26 02:33:461752 MockWrite data_writes[] = {
1753 MockWrite("GET / HTTP/1.1\r\n"
1754 "Host: www.google.com\r\n"
1755 "Connection: keep-alive\r\n\r\n"),
1756 };
1757
1758 MockRead data_reads[] = {
1759 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1760 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1761 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1762 // Large content-length -- won't matter, as connection will be reset.
1763 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061764 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461765 };
1766
[email protected]31a2bfe2010-02-09 08:03:391767 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1768 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071769 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411770 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461771
[email protected]49639fa2011-12-20 23:22:411772 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461773 EXPECT_EQ(ERR_IO_PENDING, rv);
1774
1775 rv = callback.WaitForResult();
1776 EXPECT_EQ(0, rv);
1777
[email protected]b8015c42013-12-24 15:18:191778 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
1779 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
1780
[email protected]861fcd52009-08-26 02:33:461781 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501782 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461783 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1784}
1785
[email protected]2d2697f92009-02-18 21:00:321786// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1787// connection.
[email protected]23e482282013-06-14 16:08:021788TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421789 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321790 request.method = "GET";
1791 request.url = GURL("http://www.google.com/");
1792 request.load_flags = 0;
1793
[email protected]58e32bb2013-01-21 18:23:251794 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071795 session_deps_.net_log = &log;
1796 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271797
[email protected]2d2697f92009-02-18 21:00:321798 MockWrite data_writes1[] = {
1799 MockWrite("GET / HTTP/1.1\r\n"
1800 "Host: www.google.com\r\n"
1801 "Connection: keep-alive\r\n\r\n"),
1802
1803 // After calling trans->RestartWithAuth(), this is the request we should
1804 // be issuing -- the final header line contains the credentials.
1805 MockWrite("GET / HTTP/1.1\r\n"
1806 "Host: www.google.com\r\n"
1807 "Connection: keep-alive\r\n"
1808 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1809 };
1810
1811 MockRead data_reads1[] = {
1812 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1813 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1814 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1815 MockRead("Content-Length: 14\r\n\r\n"),
1816 MockRead("Unauthorized\r\n"),
1817
1818 // Lastly, the server responds with the actual content.
1819 MockRead("HTTP/1.1 200 OK\r\n"),
1820 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501821 MockRead("Content-Length: 5\r\n\r\n"),
1822 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321823 };
1824
[email protected]2d0a4f92011-05-05 16:38:461825 // If there is a regression where we disconnect a Keep-Alive
1826 // connection during an auth roundtrip, we'll end up reading this.
1827 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061828 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461829 };
1830
[email protected]31a2bfe2010-02-09 08:03:391831 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1832 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461833 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1834 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071835 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1836 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321837
[email protected]49639fa2011-12-20 23:22:411838 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321839
[email protected]262eec82013-03-19 21:01:361840 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411842 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421843 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321844
1845 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421846 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321847
[email protected]58e32bb2013-01-21 18:23:251848 LoadTimingInfo load_timing_info1;
1849 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1850 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1851
[email protected]1c773ea12009-04-28 19:58:421852 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501853 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041854 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321855
[email protected]49639fa2011-12-20 23:22:411856 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321857
[email protected]49639fa2011-12-20 23:22:411858 rv = trans->RestartWithAuth(
1859 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421860 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321861
1862 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421863 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321864
[email protected]58e32bb2013-01-21 18:23:251865 LoadTimingInfo load_timing_info2;
1866 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1867 TestLoadTimingReused(load_timing_info2);
1868 // The load timing after restart should have the same socket ID, and times
1869 // those of the first load timing.
1870 EXPECT_LE(load_timing_info1.receive_headers_end,
1871 load_timing_info2.send_start);
1872 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1873
[email protected]2d2697f92009-02-18 21:00:321874 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501875 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321876 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501877 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:191878
1879 std::string response_data;
1880 rv = ReadTransaction(trans.get(), &response_data);
1881 EXPECT_EQ(OK, rv);
1882 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1883 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:321884}
1885
1886// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1887// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021888TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421889 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321890 request.method = "GET";
1891 request.url = GURL("http://www.google.com/");
1892 request.load_flags = 0;
1893
[email protected]bb88e1d32013-05-03 23:11:071894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271895
[email protected]2d2697f92009-02-18 21:00:321896 MockWrite data_writes1[] = {
1897 MockWrite("GET / HTTP/1.1\r\n"
1898 "Host: www.google.com\r\n"
1899 "Connection: keep-alive\r\n\r\n"),
1900
1901 // After calling trans->RestartWithAuth(), this is the request we should
1902 // be issuing -- the final header line contains the credentials.
1903 MockWrite("GET / HTTP/1.1\r\n"
1904 "Host: www.google.com\r\n"
1905 "Connection: keep-alive\r\n"
1906 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1907 };
1908
[email protected]2d2697f92009-02-18 21:00:321909 MockRead data_reads1[] = {
1910 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1911 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311912 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321913
1914 // Lastly, the server responds with the actual content.
1915 MockRead("HTTP/1.1 200 OK\r\n"),
1916 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501917 MockRead("Content-Length: 5\r\n\r\n"),
1918 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321919 };
1920
[email protected]2d0a4f92011-05-05 16:38:461921 // An incorrect reconnect would cause this to be read.
1922 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061923 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461924 };
1925
[email protected]31a2bfe2010-02-09 08:03:391926 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1927 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461928 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1929 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071930 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1931 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321932
[email protected]49639fa2011-12-20 23:22:411933 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321934
[email protected]262eec82013-03-19 21:01:361935 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501936 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411937 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421938 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321939
1940 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421941 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321942
[email protected]1c773ea12009-04-28 19:58:421943 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501944 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041945 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321946
[email protected]49639fa2011-12-20 23:22:411947 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321948
[email protected]49639fa2011-12-20 23:22:411949 rv = trans->RestartWithAuth(
1950 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421951 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321952
1953 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421954 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321955
1956 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501957 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321958 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501959 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321960}
1961
1962// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1963// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:021964TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421965 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321966 request.method = "GET";
1967 request.url = GURL("http://www.google.com/");
1968 request.load_flags = 0;
1969
[email protected]bb88e1d32013-05-03 23:11:071970 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271971
[email protected]2d2697f92009-02-18 21:00:321972 MockWrite data_writes1[] = {
1973 MockWrite("GET / HTTP/1.1\r\n"
1974 "Host: www.google.com\r\n"
1975 "Connection: keep-alive\r\n\r\n"),
1976
1977 // After calling trans->RestartWithAuth(), this is the request we should
1978 // be issuing -- the final header line contains the credentials.
1979 MockWrite("GET / HTTP/1.1\r\n"
1980 "Host: www.google.com\r\n"
1981 "Connection: keep-alive\r\n"
1982 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1983 };
1984
1985 // Respond with 5 kb of response body.
1986 std::string large_body_string("Unauthorized");
1987 large_body_string.append(5 * 1024, ' ');
1988 large_body_string.append("\r\n");
1989
1990 MockRead data_reads1[] = {
1991 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1992 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1993 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1994 // 5134 = 12 + 5 * 1024 + 2
1995 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061996 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:321997
1998 // Lastly, the server responds with the actual content.
1999 MockRead("HTTP/1.1 200 OK\r\n"),
2000 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502001 MockRead("Content-Length: 5\r\n\r\n"),
2002 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322003 };
2004
[email protected]2d0a4f92011-05-05 16:38:462005 // An incorrect reconnect would cause this to be read.
2006 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062007 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462008 };
2009
[email protected]31a2bfe2010-02-09 08:03:392010 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2011 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462012 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2013 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072014 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2015 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322016
[email protected]49639fa2011-12-20 23:22:412017 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322018
[email protected]262eec82013-03-19 21:01:362019 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502020 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412021 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422022 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322023
2024 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422025 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322026
[email protected]1c773ea12009-04-28 19:58:422027 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502028 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042029 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322030
[email protected]49639fa2011-12-20 23:22:412031 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322032
[email protected]49639fa2011-12-20 23:22:412033 rv = trans->RestartWithAuth(
2034 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422035 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322036
2037 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422038 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322039
2040 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502041 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322042 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502043 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322044}
2045
2046// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312047// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022048TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312049 HttpRequestInfo request;
2050 request.method = "GET";
2051 request.url = GURL("http://www.google.com/");
2052 request.load_flags = 0;
2053
[email protected]bb88e1d32013-05-03 23:11:072054 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272055
[email protected]11203f012009-11-12 23:02:312056 MockWrite data_writes1[] = {
2057 MockWrite("GET / HTTP/1.1\r\n"
2058 "Host: www.google.com\r\n"
2059 "Connection: keep-alive\r\n\r\n"),
2060 // This simulates the seemingly successful write to a closed connection
2061 // if the bug is not fixed.
2062 MockWrite("GET / HTTP/1.1\r\n"
2063 "Host: www.google.com\r\n"
2064 "Connection: keep-alive\r\n"
2065 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2066 };
2067
2068 MockRead data_reads1[] = {
2069 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2070 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2071 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2072 MockRead("Content-Length: 14\r\n\r\n"),
2073 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062074 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312075 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062076 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312077 };
2078
2079 // After calling trans->RestartWithAuth(), this is the request we should
2080 // be issuing -- the final header line contains the credentials.
2081 MockWrite data_writes2[] = {
2082 MockWrite("GET / HTTP/1.1\r\n"
2083 "Host: www.google.com\r\n"
2084 "Connection: keep-alive\r\n"
2085 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2086 };
2087
2088 // Lastly, the server responds with the actual content.
2089 MockRead data_reads2[] = {
2090 MockRead("HTTP/1.1 200 OK\r\n"),
2091 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502092 MockRead("Content-Length: 5\r\n\r\n"),
2093 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312094 };
2095
[email protected]31a2bfe2010-02-09 08:03:392096 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2097 data_writes1, arraysize(data_writes1));
2098 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2099 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072100 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2101 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312102
[email protected]49639fa2011-12-20 23:22:412103 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312104
[email protected]262eec82013-03-19 21:01:362105 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412107 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312108 EXPECT_EQ(ERR_IO_PENDING, rv);
2109
2110 rv = callback1.WaitForResult();
2111 EXPECT_EQ(OK, rv);
2112
2113 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502114 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042115 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312116
[email protected]49639fa2011-12-20 23:22:412117 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312118
[email protected]49639fa2011-12-20 23:22:412119 rv = trans->RestartWithAuth(
2120 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312121 EXPECT_EQ(ERR_IO_PENDING, rv);
2122
2123 rv = callback2.WaitForResult();
2124 EXPECT_EQ(OK, rv);
2125
2126 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502127 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312128 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502129 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312130}
2131
[email protected]394816e92010-08-03 07:38:592132// Test the request-challenge-retry sequence for basic auth, over a connection
2133// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022134TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592135 HttpRequestInfo request;
2136 request.method = "GET";
2137 request.url = GURL("https://www.google.com/");
2138 // when the no authentication data flag is set.
2139 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2140
[email protected]cb9bf6ca2011-01-28 13:15:272141 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072142 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202143 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292144 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072145 session_deps_.net_log = log.bound().net_log();
2146 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272147
[email protected]394816e92010-08-03 07:38:592148 // Since we have proxy, should try to establish tunnel.
2149 MockWrite data_writes1[] = {
2150 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2151 "Host: www.google.com\r\n"
2152 "Proxy-Connection: keep-alive\r\n\r\n"),
2153
2154 // After calling trans->RestartWithAuth(), this is the request we should
2155 // be issuing -- the final header line contains the credentials.
2156 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2157 "Host: www.google.com\r\n"
2158 "Proxy-Connection: keep-alive\r\n"
2159 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2160
2161 MockWrite("GET / HTTP/1.1\r\n"
2162 "Host: www.google.com\r\n"
2163 "Connection: keep-alive\r\n\r\n"),
2164 };
2165
2166 // The proxy responds to the connect with a 407, using a persistent
2167 // connection.
2168 MockRead data_reads1[] = {
2169 // No credentials.
2170 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2171 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2172 MockRead("Proxy-Connection: close\r\n\r\n"),
2173
2174 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2175
2176 MockRead("HTTP/1.1 200 OK\r\n"),
2177 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502178 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062179 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592180 };
2181
2182 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2183 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072184 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062185 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592187
[email protected]49639fa2011-12-20 23:22:412188 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592189
[email protected]262eec82013-03-19 21:01:362190 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502192
[email protected]49639fa2011-12-20 23:22:412193 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592194 EXPECT_EQ(ERR_IO_PENDING, rv);
2195
2196 rv = callback1.WaitForResult();
2197 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572198 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402199 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592200 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402201 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592202 NetLog::PHASE_NONE);
2203 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402204 entries, pos,
[email protected]394816e92010-08-03 07:38:592205 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2206 NetLog::PHASE_NONE);
2207
2208 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502209 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502210 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592211 EXPECT_EQ(407, response->headers->response_code());
2212 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042213 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592214
[email protected]029c83b62013-01-24 05:28:202215 LoadTimingInfo load_timing_info;
2216 // CONNECT requests and responses are handled at the connect job level, so
2217 // the transaction does not yet have a connection.
2218 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2219
[email protected]49639fa2011-12-20 23:22:412220 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592221
[email protected]49639fa2011-12-20 23:22:412222 rv = trans->RestartWithAuth(
2223 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592224 EXPECT_EQ(ERR_IO_PENDING, rv);
2225
2226 rv = callback2.WaitForResult();
2227 EXPECT_EQ(OK, rv);
2228
2229 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502230 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592231
2232 EXPECT_TRUE(response->headers->IsKeepAlive());
2233 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502234 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592235 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2236
2237 // The password prompt info should not be set.
2238 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502239
[email protected]029c83b62013-01-24 05:28:202240 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2241 TestLoadTimingNotReusedWithPac(load_timing_info,
2242 CONNECT_TIMING_HAS_SSL_TIMES);
2243
[email protected]0b0bf032010-09-21 18:08:502244 trans.reset();
[email protected]102e27c2011-02-23 01:01:312245 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592246}
2247
[email protected]11203f012009-11-12 23:02:312248// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322249// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022250TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272251 HttpRequestInfo request;
2252 request.method = "GET";
2253 request.url = GURL("https://www.google.com/");
2254 // Ensure that proxy authentication is attempted even
2255 // when the no authentication data flag is set.
2256 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2257
[email protected]2d2697f92009-02-18 21:00:322258 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072259 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292260 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072261 session_deps_.net_log = log.bound().net_log();
2262 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322263
[email protected]262eec82013-03-19 21:01:362264 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502265 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322266
[email protected]2d2697f92009-02-18 21:00:322267 // Since we have proxy, should try to establish tunnel.
2268 MockWrite data_writes1[] = {
2269 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452270 "Host: www.google.com\r\n"
2271 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322272
2273 // After calling trans->RestartWithAuth(), this is the request we should
2274 // be issuing -- the final header line contains the credentials.
2275 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2276 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452277 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322278 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2279 };
2280
2281 // The proxy responds to the connect with a 407, using a persistent
2282 // connection.
2283 MockRead data_reads1[] = {
2284 // No credentials.
2285 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2286 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2287 MockRead("Content-Length: 10\r\n\r\n"),
2288 MockRead("0123456789"),
2289
2290 // Wrong credentials (wrong password).
2291 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2292 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2293 MockRead("Content-Length: 10\r\n\r\n"),
2294 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062295 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322296 };
2297
[email protected]31a2bfe2010-02-09 08:03:392298 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2299 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072300 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322301
[email protected]49639fa2011-12-20 23:22:412302 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322303
[email protected]49639fa2011-12-20 23:22:412304 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422305 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322306
2307 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422308 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572309 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402310 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392311 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402312 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392313 NetLog::PHASE_NONE);
2314 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402315 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392316 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2317 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322318
[email protected]1c773ea12009-04-28 19:58:422319 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502320 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502321 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322322 EXPECT_TRUE(response->headers->IsKeepAlive());
2323 EXPECT_EQ(407, response->headers->response_code());
2324 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422325 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042326 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322327
[email protected]49639fa2011-12-20 23:22:412328 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322329
2330 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412331 rv = trans->RestartWithAuth(
2332 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422333 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322334
2335 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422336 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322337
2338 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502339 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502340 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322341 EXPECT_TRUE(response->headers->IsKeepAlive());
2342 EXPECT_EQ(407, response->headers->response_code());
2343 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422344 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042345 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132346
[email protected]e60e47a2010-07-14 03:37:182347 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2348 // out of scope.
[email protected]102e27c2011-02-23 01:01:312349 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322350}
2351
[email protected]a8e9b162009-03-12 00:06:442352// Test that we don't read the response body when we fail to establish a tunnel,
2353// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022354TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272355 HttpRequestInfo request;
2356 request.method = "GET";
2357 request.url = GURL("https://www.google.com/");
2358 request.load_flags = 0;
2359
[email protected]a8e9b162009-03-12 00:06:442360 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072361 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442362
[email protected]bb88e1d32013-05-03 23:11:072363 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442364
[email protected]262eec82013-03-19 21:01:362365 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502366 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442367
[email protected]a8e9b162009-03-12 00:06:442368 // Since we have proxy, should try to establish tunnel.
2369 MockWrite data_writes[] = {
2370 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452371 "Host: www.google.com\r\n"
2372 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442373 };
2374
2375 // The proxy responds to the connect with a 407.
2376 MockRead data_reads[] = {
2377 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2378 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2379 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062380 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442381 };
2382
[email protected]31a2bfe2010-02-09 08:03:392383 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2384 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072385 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442386
[email protected]49639fa2011-12-20 23:22:412387 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442388
[email protected]49639fa2011-12-20 23:22:412389 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422390 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442391
2392 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422393 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442394
[email protected]1c773ea12009-04-28 19:58:422395 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502396 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442397
2398 EXPECT_TRUE(response->headers->IsKeepAlive());
2399 EXPECT_EQ(407, response->headers->response_code());
2400 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422401 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442402
2403 std::string response_data;
2404 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422405 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182406
2407 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312408 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442409}
2410
[email protected]8fdbcd22010-05-05 02:54:522411// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2412// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022413TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522414 HttpRequestInfo request;
2415 request.method = "GET";
2416 request.url = GURL("http://www.google.com/");
2417 request.load_flags = 0;
2418
[email protected]cb9bf6ca2011-01-28 13:15:272419 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072420 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272421 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:072422 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:272423
[email protected]8fdbcd22010-05-05 02:54:522424 MockWrite data_writes1[] = {
2425 MockWrite("GET / HTTP/1.1\r\n"
2426 "Host: www.google.com\r\n"
2427 "Connection: keep-alive\r\n\r\n"),
2428 };
2429
2430 MockRead data_reads1[] = {
2431 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2432 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2433 // Large content-length -- won't matter, as connection will be reset.
2434 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062435 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522436 };
2437
2438 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2439 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072440 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522441
[email protected]49639fa2011-12-20 23:22:412442 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522443
[email protected]49639fa2011-12-20 23:22:412444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522445 EXPECT_EQ(ERR_IO_PENDING, rv);
2446
2447 rv = callback.WaitForResult();
2448 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2449}
2450
[email protected]7a67a8152010-11-05 18:31:102451// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2452// through a non-authenticating proxy. The request should fail with
2453// ERR_UNEXPECTED_PROXY_AUTH.
2454// Note that it is impossible to detect if an HTTP server returns a 407 through
2455// a non-authenticating proxy - there is nothing to indicate whether the
2456// response came from the proxy or the server, so it is treated as if the proxy
2457// issued the challenge.
[email protected]23e482282013-06-14 16:08:022458TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232459 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272460 HttpRequestInfo request;
2461 request.method = "GET";
2462 request.url = GURL("https://www.google.com/");
2463
[email protected]bb88e1d32013-05-03 23:11:072464 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292465 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072466 session_deps_.net_log = log.bound().net_log();
2467 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102468
[email protected]7a67a8152010-11-05 18:31:102469 // Since we have proxy, should try to establish tunnel.
2470 MockWrite data_writes1[] = {
2471 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2472 "Host: www.google.com\r\n"
2473 "Proxy-Connection: keep-alive\r\n\r\n"),
2474
2475 MockWrite("GET / HTTP/1.1\r\n"
2476 "Host: www.google.com\r\n"
2477 "Connection: keep-alive\r\n\r\n"),
2478 };
2479
2480 MockRead data_reads1[] = {
2481 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2482
2483 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2484 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2485 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062486 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102487 };
2488
2489 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2490 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072491 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062492 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102494
[email protected]49639fa2011-12-20 23:22:412495 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102496
[email protected]262eec82013-03-19 21:01:362497 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502498 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102499
[email protected]49639fa2011-12-20 23:22:412500 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102501 EXPECT_EQ(ERR_IO_PENDING, rv);
2502
2503 rv = callback1.WaitForResult();
2504 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572505 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402506 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102507 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402508 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102509 NetLog::PHASE_NONE);
2510 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402511 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102512 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2513 NetLog::PHASE_NONE);
2514}
[email protected]2df19bb2010-08-25 20:13:462515
[email protected]029c83b62013-01-24 05:28:202516// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022517TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202518 HttpRequestInfo request1;
2519 request1.method = "GET";
2520 request1.url = GURL("https://www.google.com/1");
2521
2522 HttpRequestInfo request2;
2523 request2.method = "GET";
2524 request2.url = GURL("https://www.google.com/2");
2525
2526 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072527 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202528 ProxyService::CreateFixed("PROXY myproxy:70"));
2529 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072530 session_deps_.net_log = log.bound().net_log();
2531 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202532
2533 // Since we have proxy, should try to establish tunnel.
2534 MockWrite data_writes1[] = {
2535 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2536 "Host: www.google.com\r\n"
2537 "Proxy-Connection: keep-alive\r\n\r\n"),
2538
2539 MockWrite("GET /1 HTTP/1.1\r\n"
2540 "Host: www.google.com\r\n"
2541 "Connection: keep-alive\r\n\r\n"),
2542
2543 MockWrite("GET /2 HTTP/1.1\r\n"
2544 "Host: www.google.com\r\n"
2545 "Connection: keep-alive\r\n\r\n"),
2546 };
2547
2548 // The proxy responds to the connect with a 407, using a persistent
2549 // connection.
2550 MockRead data_reads1[] = {
2551 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2552
2553 MockRead("HTTP/1.1 200 OK\r\n"),
2554 MockRead("Content-Length: 1\r\n\r\n"),
2555 MockRead(SYNCHRONOUS, "1"),
2556
2557 MockRead("HTTP/1.1 200 OK\r\n"),
2558 MockRead("Content-Length: 2\r\n\r\n"),
2559 MockRead(SYNCHRONOUS, "22"),
2560 };
2561
2562 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2563 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072564 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202565 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072566 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202567
2568 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362569 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502570 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202571
2572 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2573 EXPECT_EQ(ERR_IO_PENDING, rv);
2574
2575 rv = callback1.WaitForResult();
2576 EXPECT_EQ(OK, rv);
2577
2578 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2579 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502580 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202581 EXPECT_EQ(1, response1->headers->GetContentLength());
2582
2583 LoadTimingInfo load_timing_info1;
2584 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2585 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2586
2587 trans1.reset();
2588
2589 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362590 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202592
2593 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2594 EXPECT_EQ(ERR_IO_PENDING, rv);
2595
2596 rv = callback2.WaitForResult();
2597 EXPECT_EQ(OK, rv);
2598
2599 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2600 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502601 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202602 EXPECT_EQ(2, response2->headers->GetContentLength());
2603
2604 LoadTimingInfo load_timing_info2;
2605 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2606 TestLoadTimingReused(load_timing_info2);
2607
2608 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2609
2610 trans2.reset();
2611 session->CloseAllConnections();
2612}
2613
2614// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022615TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202616 HttpRequestInfo request1;
2617 request1.method = "GET";
2618 request1.url = GURL("https://www.google.com/1");
2619
2620 HttpRequestInfo request2;
2621 request2.method = "GET";
2622 request2.url = GURL("https://www.google.com/2");
2623
2624 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072625 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202626 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2627 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072628 session_deps_.net_log = log.bound().net_log();
2629 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202630
2631 // Since we have proxy, should try to establish tunnel.
2632 MockWrite data_writes1[] = {
2633 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2634 "Host: www.google.com\r\n"
2635 "Proxy-Connection: keep-alive\r\n\r\n"),
2636
2637 MockWrite("GET /1 HTTP/1.1\r\n"
2638 "Host: www.google.com\r\n"
2639 "Connection: keep-alive\r\n\r\n"),
2640
2641 MockWrite("GET /2 HTTP/1.1\r\n"
2642 "Host: www.google.com\r\n"
2643 "Connection: keep-alive\r\n\r\n"),
2644 };
2645
2646 // The proxy responds to the connect with a 407, using a persistent
2647 // connection.
2648 MockRead data_reads1[] = {
2649 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2650
2651 MockRead("HTTP/1.1 200 OK\r\n"),
2652 MockRead("Content-Length: 1\r\n\r\n"),
2653 MockRead(SYNCHRONOUS, "1"),
2654
2655 MockRead("HTTP/1.1 200 OK\r\n"),
2656 MockRead("Content-Length: 2\r\n\r\n"),
2657 MockRead(SYNCHRONOUS, "22"),
2658 };
2659
2660 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2661 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072662 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202663 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202665
2666 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362667 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502668 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202669
2670 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2671 EXPECT_EQ(ERR_IO_PENDING, rv);
2672
2673 rv = callback1.WaitForResult();
2674 EXPECT_EQ(OK, rv);
2675
2676 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2677 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502678 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202679 EXPECT_EQ(1, response1->headers->GetContentLength());
2680
2681 LoadTimingInfo load_timing_info1;
2682 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2683 TestLoadTimingNotReusedWithPac(load_timing_info1,
2684 CONNECT_TIMING_HAS_SSL_TIMES);
2685
2686 trans1.reset();
2687
2688 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362689 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502690 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202691
2692 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2693 EXPECT_EQ(ERR_IO_PENDING, rv);
2694
2695 rv = callback2.WaitForResult();
2696 EXPECT_EQ(OK, rv);
2697
2698 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2699 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502700 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202701 EXPECT_EQ(2, response2->headers->GetContentLength());
2702
2703 LoadTimingInfo load_timing_info2;
2704 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2705 TestLoadTimingReusedWithPac(load_timing_info2);
2706
2707 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2708
2709 trans2.reset();
2710 session->CloseAllConnections();
2711}
2712
[email protected]2df19bb2010-08-25 20:13:462713// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022714TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272715 HttpRequestInfo request;
2716 request.method = "GET";
2717 request.url = GURL("http://www.google.com/");
2718
[email protected]2df19bb2010-08-25 20:13:462719 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072720 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112721 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292722 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072723 session_deps_.net_log = log.bound().net_log();
2724 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462725
[email protected]2df19bb2010-08-25 20:13:462726 // Since we have proxy, should use full url
2727 MockWrite data_writes1[] = {
2728 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2729 "Host: www.google.com\r\n"
2730 "Proxy-Connection: keep-alive\r\n\r\n"),
2731 };
2732
2733 MockRead data_reads1[] = {
2734 MockRead("HTTP/1.1 200 OK\r\n"),
2735 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2736 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062737 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462738 };
2739
2740 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2741 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072742 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062743 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462745
[email protected]49639fa2011-12-20 23:22:412746 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462747
[email protected]262eec82013-03-19 21:01:362748 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502750
[email protected]49639fa2011-12-20 23:22:412751 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462752 EXPECT_EQ(ERR_IO_PENDING, rv);
2753
2754 rv = callback1.WaitForResult();
2755 EXPECT_EQ(OK, rv);
2756
[email protected]58e32bb2013-01-21 18:23:252757 LoadTimingInfo load_timing_info;
2758 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2759 TestLoadTimingNotReused(load_timing_info,
2760 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2761
[email protected]2df19bb2010-08-25 20:13:462762 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502763 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462764
2765 EXPECT_TRUE(response->headers->IsKeepAlive());
2766 EXPECT_EQ(200, response->headers->response_code());
2767 EXPECT_EQ(100, response->headers->GetContentLength());
2768 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2769
2770 // The password prompt info should not be set.
2771 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2772}
2773
[email protected]7642b5ae2010-09-01 20:55:172774// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022775TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272776 HttpRequestInfo request;
2777 request.method = "GET";
2778 request.url = GURL("http://www.google.com/");
2779 request.load_flags = 0;
2780
[email protected]7642b5ae2010-09-01 20:55:172781 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072782 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112783 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292784 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072785 session_deps_.net_log = log.bound().net_log();
2786 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172787
[email protected]7642b5ae2010-09-01 20:55:172788 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462789 scoped_ptr<SpdyFrame> req(
2790 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172791 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2792
[email protected]23e482282013-06-14 16:08:022793 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2794 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172795 MockRead spdy_reads[] = {
2796 CreateMockRead(*resp),
2797 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062798 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172799 };
2800
[email protected]dd54bd82012-07-19 23:44:572801 DelayedSocketData spdy_data(
2802 1, // wait for one write to finish before reading.
2803 spdy_reads, arraysize(spdy_reads),
2804 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072805 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172806
[email protected]8ddf8322012-02-23 18:08:062807 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022808 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172810
[email protected]49639fa2011-12-20 23:22:412811 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172812
[email protected]262eec82013-03-19 21:01:362813 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502814 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502815
[email protected]49639fa2011-12-20 23:22:412816 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172817 EXPECT_EQ(ERR_IO_PENDING, rv);
2818
2819 rv = callback1.WaitForResult();
2820 EXPECT_EQ(OK, rv);
2821
[email protected]58e32bb2013-01-21 18:23:252822 LoadTimingInfo load_timing_info;
2823 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2824 TestLoadTimingNotReused(load_timing_info,
2825 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2826
[email protected]7642b5ae2010-09-01 20:55:172827 const HttpResponseInfo* response = trans->GetResponseInfo();
2828 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502829 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172830 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2831
2832 std::string response_data;
2833 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232834 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172835}
2836
[email protected]dc7bd1c52010-11-12 00:01:132837// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022838TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272839 HttpRequestInfo request;
2840 request.method = "GET";
2841 request.url = GURL("http://www.google.com/");
2842 request.load_flags = 0;
2843
[email protected]79cb5c12011-09-12 13:12:042844 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072845 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042846 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292847 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072848 session_deps_.net_log = log.bound().net_log();
2849 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132850
[email protected]dc7bd1c52010-11-12 00:01:132851 // The first request will be a bare GET, the second request will be a
2852 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192853 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462854 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132855 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462856 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132857 };
[email protected]ff98d7f02012-03-22 21:44:192858 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462859 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2860 arraysize(kExtraAuthorizationHeaders) / 2,
2861 false,
2862 3,
2863 LOWEST,
2864 false));
[email protected]dc7bd1c52010-11-12 00:01:132865 MockWrite spdy_writes[] = {
2866 CreateMockWrite(*req_get, 1),
2867 CreateMockWrite(*req_get_authorization, 4),
2868 };
2869
2870 // The first response is a 407 proxy authentication challenge, and the second
2871 // response will be a 200 response since the second request includes a valid
2872 // Authorization header.
2873 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462874 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132875 };
[email protected]ff98d7f02012-03-22 21:44:192876 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022877 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132878 "407 Proxy Authentication Required",
2879 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2880 1));
[email protected]ff98d7f02012-03-22 21:44:192881 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022882 spdy_util_.ConstructSpdyBodyFrame(1, true));
2883 scoped_ptr<SpdyFrame> resp_data(
2884 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2885 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132886 MockRead spdy_reads[] = {
2887 CreateMockRead(*resp_authentication, 2),
2888 CreateMockRead(*body_authentication, 3),
2889 CreateMockRead(*resp_data, 5),
2890 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:062891 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:132892 };
2893
[email protected]dd54bd82012-07-19 23:44:572894 OrderedSocketData data(
2895 spdy_reads, arraysize(spdy_reads),
2896 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072897 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:132898
[email protected]8ddf8322012-02-23 18:08:062899 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022900 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:132902
[email protected]49639fa2011-12-20 23:22:412903 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132904
[email protected]262eec82013-03-19 21:01:362905 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502906 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:132907
[email protected]49639fa2011-12-20 23:22:412908 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:132909 EXPECT_EQ(ERR_IO_PENDING, rv);
2910
2911 rv = callback1.WaitForResult();
2912 EXPECT_EQ(OK, rv);
2913
2914 const HttpResponseInfo* const response = trans->GetResponseInfo();
2915
2916 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502917 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132918 EXPECT_EQ(407, response->headers->response_code());
2919 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042920 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132921
[email protected]49639fa2011-12-20 23:22:412922 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132923
[email protected]49639fa2011-12-20 23:22:412924 rv = trans->RestartWithAuth(
2925 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:132926 EXPECT_EQ(ERR_IO_PENDING, rv);
2927
2928 rv = callback2.WaitForResult();
2929 EXPECT_EQ(OK, rv);
2930
2931 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2932
2933 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:502934 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132935 EXPECT_EQ(200, response_restart->headers->response_code());
2936 // The password prompt info should not be set.
2937 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2938}
2939
[email protected]d9da5fe2010-10-13 22:37:162940// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:022941TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272942 HttpRequestInfo request;
2943 request.method = "GET";
2944 request.url = GURL("https://www.google.com/");
2945 request.load_flags = 0;
2946
[email protected]d9da5fe2010-10-13 22:37:162947 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072948 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112949 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292950 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072951 session_deps_.net_log = log.bound().net_log();
2952 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162953
[email protected]262eec82013-03-19 21:01:362954 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502955 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162956
[email protected]d9da5fe2010-10-13 22:37:162957 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:542958 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
2959 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:162960 // fetch https://www.google.com/ via HTTP
2961
2962 const char get[] = "GET / HTTP/1.1\r\n"
2963 "Host: www.google.com\r\n"
2964 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192965 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:022966 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2967 scoped_ptr<SpdyFrame> conn_resp(
2968 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162969 const char resp[] = "HTTP/1.1 200 OK\r\n"
2970 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192971 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022972 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:192973 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:022974 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:192975 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:202976 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:042977
2978 MockWrite spdy_writes[] = {
2979 CreateMockWrite(*connect, 1),
2980 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:462981 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:042982 };
2983
[email protected]d9da5fe2010-10-13 22:37:162984 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062985 CreateMockRead(*conn_resp, 2, ASYNC),
2986 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2987 CreateMockRead(*wrapped_body, 6, ASYNC),
2988 CreateMockRead(*wrapped_body, 7, ASYNC),
2989 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162990 };
2991
[email protected]dd54bd82012-07-19 23:44:572992 OrderedSocketData spdy_data(
2993 spdy_reads, arraysize(spdy_reads),
2994 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072995 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162996
[email protected]8ddf8322012-02-23 18:08:062997 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022998 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072999 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063000 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163001 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463002 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073003 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163004
[email protected]49639fa2011-12-20 23:22:413005 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163006
[email protected]49639fa2011-12-20 23:22:413007 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163008 EXPECT_EQ(ERR_IO_PENDING, rv);
3009
3010 rv = callback1.WaitForResult();
3011 EXPECT_EQ(OK, rv);
3012
[email protected]58e32bb2013-01-21 18:23:253013 LoadTimingInfo load_timing_info;
3014 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3015 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3016
[email protected]d9da5fe2010-10-13 22:37:163017 const HttpResponseInfo* response = trans->GetResponseInfo();
3018 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503019 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163020 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3021
3022 std::string response_data;
3023 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3024 EXPECT_EQ("1234567890", response_data);
3025}
3026
3027// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023028TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273029 HttpRequestInfo request;
3030 request.method = "GET";
3031 request.url = GURL("https://www.google.com/");
3032 request.load_flags = 0;
3033
[email protected]d9da5fe2010-10-13 22:37:163034 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073035 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113036 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293037 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073038 session_deps_.net_log = log.bound().net_log();
3039 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163040
[email protected]262eec82013-03-19 21:01:363041 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163043
[email protected]d9da5fe2010-10-13 22:37:163044 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543045 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3046 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163047 // fetch https://www.google.com/ via SPDY
3048 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463049 scoped_ptr<SpdyFrame> get(
3050 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023051 scoped_ptr<SpdyFrame> wrapped_get(
3052 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3053 scoped_ptr<SpdyFrame> conn_resp(
3054 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3055 scoped_ptr<SpdyFrame> get_resp(
3056 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193057 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023058 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3059 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3060 scoped_ptr<SpdyFrame> wrapped_body(
3061 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193062 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203063 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193064 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203065 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043066
3067 MockWrite spdy_writes[] = {
3068 CreateMockWrite(*connect, 1),
3069 CreateMockWrite(*wrapped_get, 3),
3070 CreateMockWrite(*window_update_get_resp, 5),
3071 CreateMockWrite(*window_update_body, 7),
3072 };
3073
[email protected]d9da5fe2010-10-13 22:37:163074 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063075 CreateMockRead(*conn_resp, 2, ASYNC),
3076 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3077 CreateMockRead(*wrapped_body, 6, ASYNC),
3078 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163079 };
3080
[email protected]dd54bd82012-07-19 23:44:573081 OrderedSocketData spdy_data(
3082 spdy_reads, arraysize(spdy_reads),
3083 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073084 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163085
[email protected]8ddf8322012-02-23 18:08:063086 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023087 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063089 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023090 ssl2.SetNextProto(GetParam());
3091 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073092 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163093
[email protected]49639fa2011-12-20 23:22:413094 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163095
[email protected]49639fa2011-12-20 23:22:413096 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163097 EXPECT_EQ(ERR_IO_PENDING, rv);
3098
3099 rv = callback1.WaitForResult();
3100 EXPECT_EQ(OK, rv);
3101
[email protected]58e32bb2013-01-21 18:23:253102 LoadTimingInfo load_timing_info;
3103 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3104 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3105
[email protected]d9da5fe2010-10-13 22:37:163106 const HttpResponseInfo* response = trans->GetResponseInfo();
3107 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503108 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163109 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3110
3111 std::string response_data;
3112 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233113 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163114}
3115
3116// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023117TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273118 HttpRequestInfo request;
3119 request.method = "GET";
3120 request.url = GURL("https://www.google.com/");
3121 request.load_flags = 0;
3122
[email protected]d9da5fe2010-10-13 22:37:163123 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073124 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113125 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293126 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073127 session_deps_.net_log = log.bound().net_log();
3128 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163129
[email protected]262eec82013-03-19 21:01:363130 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503131 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163132
[email protected]d9da5fe2010-10-13 22:37:163133 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543134 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3135 LOWEST));
[email protected]c10b20852013-05-15 21:29:203136 scoped_ptr<SpdyFrame> get(
3137 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163138
3139 MockWrite spdy_writes[] = {
3140 CreateMockWrite(*connect, 1),
3141 CreateMockWrite(*get, 3),
3142 };
3143
[email protected]23e482282013-06-14 16:08:023144 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3145 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163146 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063147 CreateMockRead(*resp, 2, ASYNC),
3148 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163149 };
3150
[email protected]dd54bd82012-07-19 23:44:573151 OrderedSocketData spdy_data(
3152 spdy_reads, arraysize(spdy_reads),
3153 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073154 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163155
[email protected]8ddf8322012-02-23 18:08:063156 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023157 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073158 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063159 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023160 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163162
[email protected]49639fa2011-12-20 23:22:413163 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163164
[email protected]49639fa2011-12-20 23:22:413165 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163166 EXPECT_EQ(ERR_IO_PENDING, rv);
3167
3168 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173169 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163170
[email protected]4eddbc732012-08-09 05:40:173171 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163172}
3173
[email protected]f6c63db52013-02-02 00:35:223174// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3175// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023176TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223177 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3178 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073179 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223180 "https://proxy:70"));
3181 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073182 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223183 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073184 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223185
3186 HttpRequestInfo request1;
3187 request1.method = "GET";
3188 request1.url = GURL("https://www.google.com/");
3189 request1.load_flags = 0;
3190
3191 HttpRequestInfo request2;
3192 request2.method = "GET";
3193 request2.url = GURL("https://news.google.com/");
3194 request2.load_flags = 0;
3195
3196 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543197 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3198 LOWEST));
[email protected]23e482282013-06-14 16:08:023199 scoped_ptr<SpdyFrame> conn_resp1(
3200 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223201
3202 // Fetch https://www.google.com/ via HTTP.
3203 const char get1[] = "GET / HTTP/1.1\r\n"
3204 "Host: www.google.com\r\n"
3205 "Connection: keep-alive\r\n\r\n";
3206 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023207 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223208 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3209 "Content-Length: 1\r\n\r\n";
3210 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023211 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3212 scoped_ptr<SpdyFrame> wrapped_body1(
3213 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223214 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203215 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223216
3217 // CONNECT to news.google.com:443 via SPDY.
3218 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023219 spdy_util_.GetMethodKey(), "CONNECT",
3220 spdy_util_.GetPathKey(), "news.google.com:443",
3221 spdy_util_.GetHostKey(), "news.google.com",
3222 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223223 };
3224 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233225 spdy_util_.ConstructSpdyControlFrame(NULL,
3226 0,
3227 /*compressed*/ false,
3228 3,
3229 LOWEST,
3230 SYN_STREAM,
3231 CONTROL_FLAG_NONE,
3232 kConnectHeaders2,
3233 arraysize(kConnectHeaders2),
3234 0));
[email protected]23e482282013-06-14 16:08:023235 scoped_ptr<SpdyFrame> conn_resp2(
3236 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223237
3238 // Fetch https://news.google.com/ via HTTP.
3239 const char get2[] = "GET / HTTP/1.1\r\n"
3240 "Host: news.google.com\r\n"
3241 "Connection: keep-alive\r\n\r\n";
3242 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023243 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223244 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3245 "Content-Length: 2\r\n\r\n";
3246 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023247 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223248 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023249 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223250
3251 MockWrite spdy_writes[] = {
3252 CreateMockWrite(*connect1, 0),
3253 CreateMockWrite(*wrapped_get1, 2),
3254 CreateMockWrite(*connect2, 5),
3255 CreateMockWrite(*wrapped_get2, 7),
3256 };
3257
3258 MockRead spdy_reads[] = {
3259 CreateMockRead(*conn_resp1, 1, ASYNC),
3260 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3261 CreateMockRead(*wrapped_body1, 4, ASYNC),
3262 CreateMockRead(*conn_resp2, 6, ASYNC),
3263 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3264 CreateMockRead(*wrapped_body2, 9, ASYNC),
3265 MockRead(ASYNC, 0, 10),
3266 };
3267
3268 DeterministicSocketData spdy_data(
3269 spdy_reads, arraysize(spdy_reads),
3270 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073271 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223272
3273 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023274 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073275 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223276 SSLSocketDataProvider ssl2(ASYNC, OK);
3277 ssl2.was_npn_negotiated = false;
3278 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073279 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223280 SSLSocketDataProvider ssl3(ASYNC, OK);
3281 ssl3.was_npn_negotiated = false;
3282 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073283 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223284
3285 TestCompletionCallback callback;
3286
[email protected]262eec82013-03-19 21:01:363287 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503288 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223289 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3290 EXPECT_EQ(ERR_IO_PENDING, rv);
3291 // The first connect and request, each of their responses, and the body.
3292 spdy_data.RunFor(5);
3293
3294 rv = callback.WaitForResult();
3295 EXPECT_EQ(OK, rv);
3296
3297 LoadTimingInfo load_timing_info;
3298 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3299 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3300
3301 const HttpResponseInfo* response = trans->GetResponseInfo();
3302 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503303 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223304 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3305
3306 std::string response_data;
3307 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503308 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223309
[email protected]262eec82013-03-19 21:01:363310 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223312 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3313 EXPECT_EQ(ERR_IO_PENDING, rv);
3314
3315 // The second connect and request, each of their responses, and the body.
3316 spdy_data.RunFor(5);
3317 rv = callback.WaitForResult();
3318 EXPECT_EQ(OK, rv);
3319
3320 LoadTimingInfo load_timing_info2;
3321 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3322 // Even though the SPDY connection is reused, a new tunnelled connection has
3323 // to be created, so the socket's load timing looks like a fresh connection.
3324 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3325
3326 // The requests should have different IDs, since they each are using their own
3327 // separate stream.
3328 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3329
[email protected]90499482013-06-01 00:39:503330 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223331}
3332
3333// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3334// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023335TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223336 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3337 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073338 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223339 "https://proxy:70"));
3340 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073341 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223342 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073343 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223344
3345 HttpRequestInfo request1;
3346 request1.method = "GET";
3347 request1.url = GURL("https://www.google.com/");
3348 request1.load_flags = 0;
3349
3350 HttpRequestInfo request2;
3351 request2.method = "GET";
3352 request2.url = GURL("https://www.google.com/2");
3353 request2.load_flags = 0;
3354
3355 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543356 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3357 LOWEST));
[email protected]23e482282013-06-14 16:08:023358 scoped_ptr<SpdyFrame> conn_resp1(
3359 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223360
3361 // Fetch https://www.google.com/ via HTTP.
3362 const char get1[] = "GET / HTTP/1.1\r\n"
3363 "Host: www.google.com\r\n"
3364 "Connection: keep-alive\r\n\r\n";
3365 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023366 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223367 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3368 "Content-Length: 1\r\n\r\n";
3369 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023370 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3371 scoped_ptr<SpdyFrame> wrapped_body1(
3372 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223373 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203374 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223375
3376 // Fetch https://www.google.com/2 via HTTP.
3377 const char get2[] = "GET /2 HTTP/1.1\r\n"
3378 "Host: www.google.com\r\n"
3379 "Connection: keep-alive\r\n\r\n";
3380 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023381 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223382 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3383 "Content-Length: 2\r\n\r\n";
3384 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023385 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223386 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023387 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223388
3389 MockWrite spdy_writes[] = {
3390 CreateMockWrite(*connect1, 0),
3391 CreateMockWrite(*wrapped_get1, 2),
3392 CreateMockWrite(*wrapped_get2, 5),
3393 };
3394
3395 MockRead spdy_reads[] = {
3396 CreateMockRead(*conn_resp1, 1, ASYNC),
3397 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3398 CreateMockRead(*wrapped_body1, 4, ASYNC),
3399 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3400 CreateMockRead(*wrapped_body2, 7, ASYNC),
3401 MockRead(ASYNC, 0, 8),
3402 };
3403
3404 DeterministicSocketData spdy_data(
3405 spdy_reads, arraysize(spdy_reads),
3406 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073407 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223408
3409 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023410 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073411 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223412 SSLSocketDataProvider ssl2(ASYNC, OK);
3413 ssl2.was_npn_negotiated = false;
3414 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073415 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223416
3417 TestCompletionCallback callback;
3418
[email protected]262eec82013-03-19 21:01:363419 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223421 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3422 EXPECT_EQ(ERR_IO_PENDING, rv);
3423 // The first connect and request, each of their responses, and the body.
3424 spdy_data.RunFor(5);
3425
3426 rv = callback.WaitForResult();
3427 EXPECT_EQ(OK, rv);
3428
3429 LoadTimingInfo load_timing_info;
3430 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3431 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3432
3433 const HttpResponseInfo* response = trans->GetResponseInfo();
3434 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503435 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223436 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3437
3438 std::string response_data;
3439 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503440 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223441 trans.reset();
3442
[email protected]262eec82013-03-19 21:01:363443 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223445 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3446 EXPECT_EQ(ERR_IO_PENDING, rv);
3447
3448 // The second request, response, and body. There should not be a second
3449 // connect.
3450 spdy_data.RunFor(3);
3451 rv = callback.WaitForResult();
3452 EXPECT_EQ(OK, rv);
3453
3454 LoadTimingInfo load_timing_info2;
3455 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3456 TestLoadTimingReused(load_timing_info2);
3457
3458 // The requests should have the same ID.
3459 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3460
[email protected]90499482013-06-01 00:39:503461 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223462}
3463
3464// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3465// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023466TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223467 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3468 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073469 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223470 "https://proxy:70"));
3471 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073472 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223473 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073474 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223475
3476 HttpRequestInfo request1;
3477 request1.method = "GET";
3478 request1.url = GURL("http://www.google.com/");
3479 request1.load_flags = 0;
3480
3481 HttpRequestInfo request2;
3482 request2.method = "GET";
3483 request2.url = GURL("http://news.google.com/");
3484 request2.load_flags = 0;
3485
3486 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023487 scoped_ptr<SpdyHeaderBlock> headers(
3488 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233489 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023490 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3491 scoped_ptr<SpdyFrame> get_resp1(
3492 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3493 scoped_ptr<SpdyFrame> body1(
3494 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223495
3496 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023497 scoped_ptr<SpdyHeaderBlock> headers2(
3498 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233499 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023500 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3501 scoped_ptr<SpdyFrame> get_resp2(
3502 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3503 scoped_ptr<SpdyFrame> body2(
3504 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223505
3506 MockWrite spdy_writes[] = {
3507 CreateMockWrite(*get1, 0),
3508 CreateMockWrite(*get2, 3),
3509 };
3510
3511 MockRead spdy_reads[] = {
3512 CreateMockRead(*get_resp1, 1, ASYNC),
3513 CreateMockRead(*body1, 2, ASYNC),
3514 CreateMockRead(*get_resp2, 4, ASYNC),
3515 CreateMockRead(*body2, 5, ASYNC),
3516 MockRead(ASYNC, 0, 6),
3517 };
3518
3519 DeterministicSocketData spdy_data(
3520 spdy_reads, arraysize(spdy_reads),
3521 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073522 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223523
3524 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023525 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073526 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223527
3528 TestCompletionCallback callback;
3529
[email protected]262eec82013-03-19 21:01:363530 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503531 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223532 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3533 EXPECT_EQ(ERR_IO_PENDING, rv);
3534 spdy_data.RunFor(2);
3535
3536 rv = callback.WaitForResult();
3537 EXPECT_EQ(OK, rv);
3538
3539 LoadTimingInfo load_timing_info;
3540 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3541 TestLoadTimingNotReused(load_timing_info,
3542 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3543
3544 const HttpResponseInfo* response = trans->GetResponseInfo();
3545 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503546 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223547 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3548
3549 std::string response_data;
3550 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503551 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223552 spdy_data.RunFor(1);
3553 EXPECT_EQ(1, callback.WaitForResult());
3554 // Delete the first request, so the second one can reuse the socket.
3555 trans.reset();
3556
[email protected]262eec82013-03-19 21:01:363557 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223559 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3560 EXPECT_EQ(ERR_IO_PENDING, rv);
3561
3562 spdy_data.RunFor(2);
3563 rv = callback.WaitForResult();
3564 EXPECT_EQ(OK, rv);
3565
3566 LoadTimingInfo load_timing_info2;
3567 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3568 TestLoadTimingReused(load_timing_info2);
3569
3570 // The requests should have the same ID.
3571 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3572
[email protected]90499482013-06-01 00:39:503573 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223574 spdy_data.RunFor(1);
3575 EXPECT_EQ(2, callback.WaitForResult());
3576}
3577
[email protected]2df19bb2010-08-25 20:13:463578// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023579TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463580 HttpRequestInfo request;
3581 request.method = "GET";
3582 request.url = GURL("http://www.google.com/");
3583 // when the no authentication data flag is set.
3584 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3585
[email protected]79cb5c12011-09-12 13:12:043586 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073587 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043588 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293589 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073590 session_deps_.net_log = log.bound().net_log();
3591 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273592
[email protected]2df19bb2010-08-25 20:13:463593 // Since we have proxy, should use full url
3594 MockWrite data_writes1[] = {
3595 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3596 "Host: www.google.com\r\n"
3597 "Proxy-Connection: keep-alive\r\n\r\n"),
3598
3599 // After calling trans->RestartWithAuth(), this is the request we should
3600 // be issuing -- the final header line contains the credentials.
3601 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3602 "Host: www.google.com\r\n"
3603 "Proxy-Connection: keep-alive\r\n"
3604 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3605 };
3606
3607 // The proxy responds to the GET with a 407, using a persistent
3608 // connection.
3609 MockRead data_reads1[] = {
3610 // No credentials.
3611 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3612 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3613 MockRead("Proxy-Connection: keep-alive\r\n"),
3614 MockRead("Content-Length: 0\r\n\r\n"),
3615
3616 MockRead("HTTP/1.1 200 OK\r\n"),
3617 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3618 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063619 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463620 };
3621
3622 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3623 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073624 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063625 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463627
[email protected]49639fa2011-12-20 23:22:413628 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463629
[email protected]262eec82013-03-19 21:01:363630 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503632
[email protected]49639fa2011-12-20 23:22:413633 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463634 EXPECT_EQ(ERR_IO_PENDING, rv);
3635
3636 rv = callback1.WaitForResult();
3637 EXPECT_EQ(OK, rv);
3638
[email protected]58e32bb2013-01-21 18:23:253639 LoadTimingInfo load_timing_info;
3640 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3641 TestLoadTimingNotReused(load_timing_info,
3642 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3643
[email protected]2df19bb2010-08-25 20:13:463644 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503645 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503646 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463647 EXPECT_EQ(407, response->headers->response_code());
3648 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043649 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463650
[email protected]49639fa2011-12-20 23:22:413651 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463652
[email protected]49639fa2011-12-20 23:22:413653 rv = trans->RestartWithAuth(
3654 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463655 EXPECT_EQ(ERR_IO_PENDING, rv);
3656
3657 rv = callback2.WaitForResult();
3658 EXPECT_EQ(OK, rv);
3659
[email protected]58e32bb2013-01-21 18:23:253660 load_timing_info = LoadTimingInfo();
3661 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3662 // Retrying with HTTP AUTH is considered to be reusing a socket.
3663 TestLoadTimingReused(load_timing_info);
3664
[email protected]2df19bb2010-08-25 20:13:463665 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503666 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463667
3668 EXPECT_TRUE(response->headers->IsKeepAlive());
3669 EXPECT_EQ(200, response->headers->response_code());
3670 EXPECT_EQ(100, response->headers->GetContentLength());
3671 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3672
3673 // The password prompt info should not be set.
3674 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3675}
3676
[email protected]23e482282013-06-14 16:08:023677void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083678 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423679 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083680 request.method = "GET";
3681 request.url = GURL("https://www.google.com/");
3682 request.load_flags = 0;
3683
[email protected]cb9bf6ca2011-01-28 13:15:273684 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073685 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073686 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273687
[email protected]c744cf22009-02-27 07:28:083688 // Since we have proxy, should try to establish tunnel.
3689 MockWrite data_writes[] = {
3690 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453691 "Host: www.google.com\r\n"
3692 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083693 };
3694
3695 MockRead data_reads[] = {
3696 status,
3697 MockRead("Content-Length: 10\r\n\r\n"),
3698 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063699 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083700 };
3701
[email protected]31a2bfe2010-02-09 08:03:393702 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3703 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073704 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083705
[email protected]49639fa2011-12-20 23:22:413706 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083707
[email protected]262eec82013-03-19 21:01:363708 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503709 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503710
[email protected]49639fa2011-12-20 23:22:413711 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423712 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083713
3714 rv = callback.WaitForResult();
3715 EXPECT_EQ(expected_status, rv);
3716}
3717
[email protected]23e482282013-06-14 16:08:023718void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233719 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083720 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423721 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083722}
3723
[email protected]23e482282013-06-14 16:08:023724TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083725 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3726}
3727
[email protected]23e482282013-06-14 16:08:023728TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083729 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3730}
3731
[email protected]23e482282013-06-14 16:08:023732TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083733 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3734}
3735
[email protected]23e482282013-06-14 16:08:023736TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083737 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3738}
3739
[email protected]23e482282013-06-14 16:08:023740TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083741 ConnectStatusHelper(
3742 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3743}
3744
[email protected]23e482282013-06-14 16:08:023745TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083746 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3747}
3748
[email protected]23e482282013-06-14 16:08:023749TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083750 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3751}
3752
[email protected]23e482282013-06-14 16:08:023753TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083754 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3755}
3756
[email protected]23e482282013-06-14 16:08:023757TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083758 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3759}
3760
[email protected]23e482282013-06-14 16:08:023761TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083762 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3763}
3764
[email protected]23e482282013-06-14 16:08:023765TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083766 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3767}
3768
[email protected]23e482282013-06-14 16:08:023769TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083770 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3771}
3772
[email protected]23e482282013-06-14 16:08:023773TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083774 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3775}
3776
[email protected]23e482282013-06-14 16:08:023777TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083778 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3779}
3780
[email protected]23e482282013-06-14 16:08:023781TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083782 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3783}
3784
[email protected]23e482282013-06-14 16:08:023785TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083786 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3787}
3788
[email protected]23e482282013-06-14 16:08:023789TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083790 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3791}
3792
[email protected]23e482282013-06-14 16:08:023793TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083794 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3795}
3796
[email protected]23e482282013-06-14 16:08:023797TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083798 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3799}
3800
[email protected]23e482282013-06-14 16:08:023801TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083802 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3803}
3804
[email protected]23e482282013-06-14 16:08:023805TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083806 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3807}
3808
[email protected]23e482282013-06-14 16:08:023809TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083810 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3811}
3812
[email protected]23e482282013-06-14 16:08:023813TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083814 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3815}
3816
[email protected]23e482282013-06-14 16:08:023817TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083818 ConnectStatusHelperWithExpectedStatus(
3819 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543820 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083821}
3822
[email protected]23e482282013-06-14 16:08:023823TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083824 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3825}
3826
[email protected]23e482282013-06-14 16:08:023827TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083828 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3829}
3830
[email protected]23e482282013-06-14 16:08:023831TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083832 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3833}
3834
[email protected]23e482282013-06-14 16:08:023835TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083836 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3837}
3838
[email protected]23e482282013-06-14 16:08:023839TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083840 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3841}
3842
[email protected]23e482282013-06-14 16:08:023843TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083844 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3845}
3846
[email protected]23e482282013-06-14 16:08:023847TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083848 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3849}
3850
[email protected]23e482282013-06-14 16:08:023851TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083852 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3853}
3854
[email protected]23e482282013-06-14 16:08:023855TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083856 ConnectStatusHelper(
3857 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3858}
3859
[email protected]23e482282013-06-14 16:08:023860TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083861 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3862}
3863
[email protected]23e482282013-06-14 16:08:023864TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083865 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3866}
3867
[email protected]23e482282013-06-14 16:08:023868TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083869 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3870}
3871
[email protected]23e482282013-06-14 16:08:023872TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083873 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3874}
3875
[email protected]23e482282013-06-14 16:08:023876TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083877 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3878}
3879
[email protected]23e482282013-06-14 16:08:023880TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083881 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3882}
3883
[email protected]23e482282013-06-14 16:08:023884TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083885 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3886}
3887
[email protected]038e9a32008-10-08 22:40:163888// Test the flow when both the proxy server AND origin server require
3889// authentication. Again, this uses basic auth for both since that is
3890// the simplest to mock.
[email protected]23e482282013-06-14 16:08:023891TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:273892 HttpRequestInfo request;
3893 request.method = "GET";
3894 request.url = GURL("http://www.google.com/");
3895 request.load_flags = 0;
3896
[email protected]038e9a32008-10-08 22:40:163897 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:073898 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3900
3901 scoped_ptr<HttpTransaction> trans(
3902 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]038e9a32008-10-08 22:40:163903
[email protected]f9ee6b52008-11-08 06:46:233904 MockWrite data_writes1[] = {
3905 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3906 "Host: www.google.com\r\n"
3907 "Proxy-Connection: keep-alive\r\n\r\n"),
3908 };
3909
[email protected]038e9a32008-10-08 22:40:163910 MockRead data_reads1[] = {
3911 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3912 // Give a couple authenticate options (only the middle one is actually
3913 // supported).
[email protected]22927ad2009-09-21 19:56:193914 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:163915 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3916 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3917 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3918 // Large content-length -- won't matter, as connection will be reset.
3919 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063920 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:163921 };
3922
3923 // After calling trans->RestartWithAuth() the first time, this is the
3924 // request we should be issuing -- the final header line contains the
3925 // proxy's credentials.
3926 MockWrite data_writes2[] = {
3927 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3928 "Host: www.google.com\r\n"
3929 "Proxy-Connection: keep-alive\r\n"
3930 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3931 };
3932
3933 // Now the proxy server lets the request pass through to origin server.
3934 // The origin server responds with a 401.
3935 MockRead data_reads2[] = {
3936 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3937 // Note: We are using the same realm-name as the proxy server. This is
3938 // completely valid, as realms are unique across hosts.
3939 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3940 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3941 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063942 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:163943 };
3944
3945 // After calling trans->RestartWithAuth() the second time, we should send
3946 // the credentials for both the proxy and origin server.
3947 MockWrite data_writes3[] = {
3948 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3949 "Host: www.google.com\r\n"
3950 "Proxy-Connection: keep-alive\r\n"
3951 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3952 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3953 };
3954
3955 // Lastly we get the desired content.
3956 MockRead data_reads3[] = {
3957 MockRead("HTTP/1.0 200 OK\r\n"),
3958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3959 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063960 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:163961 };
3962
[email protected]31a2bfe2010-02-09 08:03:393963 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3964 data_writes1, arraysize(data_writes1));
3965 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3966 data_writes2, arraysize(data_writes2));
3967 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3968 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:073969 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3970 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3971 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:163972
[email protected]49639fa2011-12-20 23:22:413973 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:163974
[email protected]49639fa2011-12-20 23:22:413975 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423976 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163977
3978 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423979 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163980
[email protected]1c773ea12009-04-28 19:58:423981 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503982 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043983 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163984
[email protected]49639fa2011-12-20 23:22:413985 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:163986
[email protected]49639fa2011-12-20 23:22:413987 rv = trans->RestartWithAuth(
3988 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423989 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163990
3991 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423992 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163993
3994 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503995 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043996 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163997
[email protected]49639fa2011-12-20 23:22:413998 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:163999
[email protected]49639fa2011-12-20 23:22:414000 rv = trans->RestartWithAuth(
4001 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424002 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164003
4004 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424005 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164006
4007 response = trans->GetResponseInfo();
4008 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4009 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164010}
[email protected]4ddaf2502008-10-23 18:26:194011
[email protected]ea9dc9a2009-09-05 00:43:324012// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4013// can't hook into its internals to cause it to generate predictable NTLM
4014// authorization headers.
4015#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294016// The NTLM authentication unit tests were generated by capturing the HTTP
4017// requests and responses using Fiddler 2 and inspecting the generated random
4018// bytes in the debugger.
4019
4020// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024021TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424022 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244023 request.method = "GET";
4024 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544025
4026 // Ensure load is not disrupted by flags which suppress behaviour specific
4027 // to other auth schemes.
4028 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244029
[email protected]cb9bf6ca2011-01-28 13:15:274030 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4031 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074032 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274033
[email protected]3f918782009-02-28 01:29:244034 MockWrite data_writes1[] = {
4035 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4036 "Host: 172.22.68.17\r\n"
4037 "Connection: keep-alive\r\n\r\n"),
4038 };
4039
4040 MockRead data_reads1[] = {
4041 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044042 // Negotiate and NTLM are often requested together. However, we only want
4043 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4044 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244045 MockRead("WWW-Authenticate: NTLM\r\n"),
4046 MockRead("Connection: close\r\n"),
4047 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364048 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244049 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064050 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244051 };
4052
4053 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224054 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244055 // request we should be issuing -- the final header line contains a Type
4056 // 1 message.
4057 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4058 "Host: 172.22.68.17\r\n"
4059 "Connection: keep-alive\r\n"
4060 "Authorization: NTLM "
4061 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4062
4063 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4064 // (the credentials for the origin server). The second request continues
4065 // on the same connection.
4066 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4067 "Host: 172.22.68.17\r\n"
4068 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294069 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4070 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4071 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4072 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4073 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244074 };
4075
4076 MockRead data_reads2[] = {
4077 // The origin server responds with a Type 2 message.
4078 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4079 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294080 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244081 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4082 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4083 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4084 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4085 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4086 "BtAAAAAAA=\r\n"),
4087 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364088 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244089 MockRead("You are not authorized to view this page\r\n"),
4090
4091 // Lastly we get the desired content.
4092 MockRead("HTTP/1.1 200 OK\r\n"),
4093 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4094 MockRead("Content-Length: 13\r\n\r\n"),
4095 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064096 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244097 };
4098
[email protected]31a2bfe2010-02-09 08:03:394099 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4100 data_writes1, arraysize(data_writes1));
4101 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4102 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074103 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4104 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244105
[email protected]49639fa2011-12-20 23:22:414106 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244107
[email protected]262eec82013-03-19 21:01:364108 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504110
[email protected]49639fa2011-12-20 23:22:414111 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424112 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244113
4114 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424115 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244116
[email protected]0757e7702009-03-27 04:00:224117 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4118
[email protected]1c773ea12009-04-28 19:58:424119 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044120 ASSERT_FALSE(response == NULL);
4121 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244122
[email protected]49639fa2011-12-20 23:22:414123 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254124
[email protected]f3cf9802011-10-28 18:44:584125 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414126 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254127 EXPECT_EQ(ERR_IO_PENDING, rv);
4128
4129 rv = callback2.WaitForResult();
4130 EXPECT_EQ(OK, rv);
4131
4132 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4133
4134 response = trans->GetResponseInfo();
4135 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254136 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4137
[email protected]49639fa2011-12-20 23:22:414138 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244139
[email protected]49639fa2011-12-20 23:22:414140 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424141 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244142
[email protected]0757e7702009-03-27 04:00:224143 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424144 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244145
4146 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504147 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244148 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4149 EXPECT_EQ(13, response->headers->GetContentLength());
4150}
4151
[email protected]385a4672009-03-11 22:21:294152// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024153TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424154 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294155 request.method = "GET";
4156 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4157 request.load_flags = 0;
4158
[email protected]cb9bf6ca2011-01-28 13:15:274159 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4160 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074161 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274162
[email protected]385a4672009-03-11 22:21:294163 MockWrite data_writes1[] = {
4164 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4165 "Host: 172.22.68.17\r\n"
4166 "Connection: keep-alive\r\n\r\n"),
4167 };
4168
4169 MockRead data_reads1[] = {
4170 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044171 // Negotiate and NTLM are often requested together. However, we only want
4172 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4173 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294174 MockRead("WWW-Authenticate: NTLM\r\n"),
4175 MockRead("Connection: close\r\n"),
4176 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364177 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294178 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064179 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294180 };
4181
4182 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224183 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294184 // request we should be issuing -- the final header line contains a Type
4185 // 1 message.
4186 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4187 "Host: 172.22.68.17\r\n"
4188 "Connection: keep-alive\r\n"
4189 "Authorization: NTLM "
4190 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4191
4192 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4193 // (the credentials for the origin server). The second request continues
4194 // on the same connection.
4195 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4196 "Host: 172.22.68.17\r\n"
4197 "Connection: keep-alive\r\n"
4198 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4199 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4200 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4201 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4202 "4Ww7b7E=\r\n\r\n"),
4203 };
4204
4205 MockRead data_reads2[] = {
4206 // The origin server responds with a Type 2 message.
4207 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4208 MockRead("WWW-Authenticate: NTLM "
4209 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4210 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4211 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4212 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4213 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4214 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4215 "BtAAAAAAA=\r\n"),
4216 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364217 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294218 MockRead("You are not authorized to view this page\r\n"),
4219
4220 // Wrong password.
4221 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294222 MockRead("WWW-Authenticate: NTLM\r\n"),
4223 MockRead("Connection: close\r\n"),
4224 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364225 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294226 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064227 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294228 };
4229
4230 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224231 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294232 // request we should be issuing -- the final header line contains a Type
4233 // 1 message.
4234 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4235 "Host: 172.22.68.17\r\n"
4236 "Connection: keep-alive\r\n"
4237 "Authorization: NTLM "
4238 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4239
4240 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4241 // (the credentials for the origin server). The second request continues
4242 // on the same connection.
4243 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4244 "Host: 172.22.68.17\r\n"
4245 "Connection: keep-alive\r\n"
4246 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4247 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4248 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4249 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4250 "+4MUm7c=\r\n\r\n"),
4251 };
4252
4253 MockRead data_reads3[] = {
4254 // The origin server responds with a Type 2 message.
4255 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4256 MockRead("WWW-Authenticate: NTLM "
4257 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4258 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4259 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4260 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4261 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4262 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4263 "BtAAAAAAA=\r\n"),
4264 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364265 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294266 MockRead("You are not authorized to view this page\r\n"),
4267
4268 // Lastly we get the desired content.
4269 MockRead("HTTP/1.1 200 OK\r\n"),
4270 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4271 MockRead("Content-Length: 13\r\n\r\n"),
4272 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064273 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294274 };
4275
[email protected]31a2bfe2010-02-09 08:03:394276 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4277 data_writes1, arraysize(data_writes1));
4278 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4279 data_writes2, arraysize(data_writes2));
4280 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4281 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074282 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4283 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4284 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294285
[email protected]49639fa2011-12-20 23:22:414286 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294287
[email protected]262eec82013-03-19 21:01:364288 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504289 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504290
[email protected]49639fa2011-12-20 23:22:414291 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424292 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294293
4294 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424295 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294296
[email protected]0757e7702009-03-27 04:00:224297 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294298
[email protected]1c773ea12009-04-28 19:58:424299 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504300 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044301 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294302
[email protected]49639fa2011-12-20 23:22:414303 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294304
[email protected]0757e7702009-03-27 04:00:224305 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584306 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414307 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424308 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294309
[email protected]10af5fe72011-01-31 16:17:254310 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424311 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294312
[email protected]0757e7702009-03-27 04:00:224313 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414314 TestCompletionCallback callback3;
4315 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424316 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254317 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424318 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224319 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4320
4321 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044322 ASSERT_FALSE(response == NULL);
4323 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224324
[email protected]49639fa2011-12-20 23:22:414325 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224326
4327 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584328 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414329 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254330 EXPECT_EQ(ERR_IO_PENDING, rv);
4331
4332 rv = callback4.WaitForResult();
4333 EXPECT_EQ(OK, rv);
4334
4335 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4336
[email protected]49639fa2011-12-20 23:22:414337 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254338
4339 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414340 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424341 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224342
4343 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424344 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224345
[email protected]385a4672009-03-11 22:21:294346 response = trans->GetResponseInfo();
4347 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4348 EXPECT_EQ(13, response->headers->GetContentLength());
4349}
[email protected]ea9dc9a2009-09-05 00:43:324350#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294351
[email protected]4ddaf2502008-10-23 18:26:194352// Test reading a server response which has only headers, and no body.
4353// After some maximum number of bytes is consumed, the transaction should
4354// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024355TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424356 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194357 request.method = "GET";
4358 request.url = GURL("http://www.google.com/");
4359 request.load_flags = 0;
4360
[email protected]3fe8d2f82013-10-17 08:56:074361 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274362 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074363 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274364
[email protected]b75b7b2f2009-10-06 00:54:534365 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434366 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534367 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194368
4369 MockRead data_reads[] = {
4370 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064371 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194372 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064373 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194374 };
[email protected]31a2bfe2010-02-09 08:03:394375 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074376 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194377
[email protected]49639fa2011-12-20 23:22:414378 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194379
[email protected]49639fa2011-12-20 23:22:414380 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424381 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194382
4383 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424384 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194385
[email protected]1c773ea12009-04-28 19:58:424386 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194387 EXPECT_TRUE(response == NULL);
4388}
[email protected]f4e426b2008-11-05 00:24:494389
4390// Make sure that we don't try to reuse a TCPClientSocket when failing to
4391// establish tunnel.
4392// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024393TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234394 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274395 HttpRequestInfo request;
4396 request.method = "GET";
4397 request.url = GURL("https://www.google.com/");
4398 request.load_flags = 0;
4399
[email protected]f4e426b2008-11-05 00:24:494400 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074401 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014402
[email protected]bb88e1d32013-05-03 23:11:074403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494404
[email protected]262eec82013-03-19 21:01:364405 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504406 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494407
[email protected]f4e426b2008-11-05 00:24:494408 // Since we have proxy, should try to establish tunnel.
4409 MockWrite data_writes1[] = {
4410 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454411 "Host: www.google.com\r\n"
4412 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494413 };
4414
[email protected]77848d12008-11-14 00:00:224415 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494416 // connection. Usually a proxy would return 501 (not implemented),
4417 // or 200 (tunnel established).
4418 MockRead data_reads1[] = {
4419 MockRead("HTTP/1.1 404 Not Found\r\n"),
4420 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064421 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494422 };
4423
[email protected]31a2bfe2010-02-09 08:03:394424 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4425 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074426 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494427
[email protected]49639fa2011-12-20 23:22:414428 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494429
[email protected]49639fa2011-12-20 23:22:414430 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424431 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494432
4433 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424434 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494435
[email protected]1c773ea12009-04-28 19:58:424436 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084437 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494438
[email protected]b4404c02009-04-10 16:38:524439 // Empty the current queue. This is necessary because idle sockets are
4440 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344441 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524442
[email protected]f4e426b2008-11-05 00:24:494443 // We now check to make sure the TCPClientSocket was not added back to
4444 // the pool.
[email protected]90499482013-06-01 00:39:504445 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494446 trans.reset();
[email protected]2da659e2013-05-23 20:51:344447 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494448 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504449 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494450}
[email protected]372d34a2008-11-05 21:30:514451
[email protected]1b157c02009-04-21 01:55:404452// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024453TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424454 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404455 request.method = "GET";
4456 request.url = GURL("http://www.google.com/");
4457 request.load_flags = 0;
4458
[email protected]bb88e1d32013-05-03 23:11:074459 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274460
[email protected]262eec82013-03-19 21:01:364461 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274463
[email protected]1b157c02009-04-21 01:55:404464 MockRead data_reads[] = {
4465 // A part of the response body is received with the response headers.
4466 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4467 // The rest of the response body is received in two parts.
4468 MockRead("lo"),
4469 MockRead(" world"),
4470 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064471 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404472 };
4473
[email protected]31a2bfe2010-02-09 08:03:394474 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074475 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404476
[email protected]49639fa2011-12-20 23:22:414477 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404478
[email protected]49639fa2011-12-20 23:22:414479 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424480 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404481
4482 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424483 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404484
[email protected]1c773ea12009-04-28 19:58:424485 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504486 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404487
[email protected]90499482013-06-01 00:39:504488 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404489 std::string status_line = response->headers->GetStatusLine();
4490 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4491
[email protected]90499482013-06-01 00:39:504492 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404493
4494 std::string response_data;
4495 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424496 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404497 EXPECT_EQ("hello world", response_data);
4498
4499 // Empty the current queue. This is necessary because idle sockets are
4500 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344501 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404502
4503 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504504 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404505}
4506
[email protected]76a505b2010-08-25 06:23:004507// Make sure that we recycle a SSL socket after reading all of the response
4508// body.
[email protected]23e482282013-06-14 16:08:024509TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004510 HttpRequestInfo request;
4511 request.method = "GET";
4512 request.url = GURL("https://www.google.com/");
4513 request.load_flags = 0;
4514
4515 MockWrite data_writes[] = {
4516 MockWrite("GET / HTTP/1.1\r\n"
4517 "Host: www.google.com\r\n"
4518 "Connection: keep-alive\r\n\r\n"),
4519 };
4520
4521 MockRead data_reads[] = {
4522 MockRead("HTTP/1.1 200 OK\r\n"),
4523 MockRead("Content-Length: 11\r\n\r\n"),
4524 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064525 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004526 };
4527
[email protected]8ddf8322012-02-23 18:08:064528 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004530
4531 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4532 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074533 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004534
[email protected]49639fa2011-12-20 23:22:414535 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004536
[email protected]bb88e1d32013-05-03 23:11:074537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364538 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004540
[email protected]49639fa2011-12-20 23:22:414541 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004542
4543 EXPECT_EQ(ERR_IO_PENDING, rv);
4544 EXPECT_EQ(OK, callback.WaitForResult());
4545
4546 const HttpResponseInfo* response = trans->GetResponseInfo();
4547 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504548 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004549 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4550
[email protected]90499482013-06-01 00:39:504551 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004552
4553 std::string response_data;
4554 rv = ReadTransaction(trans.get(), &response_data);
4555 EXPECT_EQ(OK, rv);
4556 EXPECT_EQ("hello world", response_data);
4557
4558 // Empty the current queue. This is necessary because idle sockets are
4559 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344560 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004561
4562 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504563 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004564}
4565
4566// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4567// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024568TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004569 HttpRequestInfo request;
4570 request.method = "GET";
4571 request.url = GURL("https://www.google.com/");
4572 request.load_flags = 0;
4573
4574 MockWrite data_writes[] = {
4575 MockWrite("GET / HTTP/1.1\r\n"
4576 "Host: www.google.com\r\n"
4577 "Connection: keep-alive\r\n\r\n"),
4578 MockWrite("GET / HTTP/1.1\r\n"
4579 "Host: www.google.com\r\n"
4580 "Connection: keep-alive\r\n\r\n"),
4581 };
4582
4583 MockRead data_reads[] = {
4584 MockRead("HTTP/1.1 200 OK\r\n"),
4585 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064586 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004587 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064588 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004589 };
4590
[email protected]8ddf8322012-02-23 18:08:064591 SSLSocketDataProvider ssl(ASYNC, OK);
4592 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4594 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004595
4596 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4597 data_writes, arraysize(data_writes));
4598 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4599 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074600 session_deps_.socket_factory->AddSocketDataProvider(&data);
4601 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004602
[email protected]49639fa2011-12-20 23:22:414603 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004604
[email protected]bb88e1d32013-05-03 23:11:074605 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364606 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004608
[email protected]49639fa2011-12-20 23:22:414609 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004610
4611 EXPECT_EQ(ERR_IO_PENDING, rv);
4612 EXPECT_EQ(OK, callback.WaitForResult());
4613
4614 const HttpResponseInfo* response = trans->GetResponseInfo();
4615 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504616 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004617 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4618
[email protected]90499482013-06-01 00:39:504619 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004620
4621 std::string response_data;
4622 rv = ReadTransaction(trans.get(), &response_data);
4623 EXPECT_EQ(OK, rv);
4624 EXPECT_EQ("hello world", response_data);
4625
4626 // Empty the current queue. This is necessary because idle sockets are
4627 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344628 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004629
4630 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504631 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004632
4633 // Now start the second transaction, which should reuse the previous socket.
4634
[email protected]90499482013-06-01 00:39:504635 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004636
[email protected]49639fa2011-12-20 23:22:414637 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004638
4639 EXPECT_EQ(ERR_IO_PENDING, rv);
4640 EXPECT_EQ(OK, callback.WaitForResult());
4641
4642 response = trans->GetResponseInfo();
4643 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504644 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004645 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4646
[email protected]90499482013-06-01 00:39:504647 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004648
4649 rv = ReadTransaction(trans.get(), &response_data);
4650 EXPECT_EQ(OK, rv);
4651 EXPECT_EQ("hello world", response_data);
4652
4653 // Empty the current queue. This is necessary because idle sockets are
4654 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344655 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004656
4657 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504658 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004659}
4660
[email protected]b4404c02009-04-10 16:38:524661// Make sure that we recycle a socket after a zero-length response.
4662// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024663TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424664 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524665 request.method = "GET";
4666 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4667 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4668 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4669 "rt=prt.2642,ol.2649,xjs.2951");
4670 request.load_flags = 0;
4671
[email protected]bb88e1d32013-05-03 23:11:074672 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274673
[email protected]262eec82013-03-19 21:01:364674 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504675 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274676
[email protected]b4404c02009-04-10 16:38:524677 MockRead data_reads[] = {
4678 MockRead("HTTP/1.1 204 No Content\r\n"
4679 "Content-Length: 0\r\n"
4680 "Content-Type: text/html\r\n\r\n"),
4681 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064682 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524683 };
4684
[email protected]31a2bfe2010-02-09 08:03:394685 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074686 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524687
[email protected]49639fa2011-12-20 23:22:414688 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524689
[email protected]49639fa2011-12-20 23:22:414690 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424691 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524692
4693 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424694 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524695
[email protected]1c773ea12009-04-28 19:58:424696 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504697 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524698
[email protected]90499482013-06-01 00:39:504699 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524700 std::string status_line = response->headers->GetStatusLine();
4701 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4702
[email protected]90499482013-06-01 00:39:504703 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524704
4705 std::string response_data;
4706 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424707 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524708 EXPECT_EQ("", response_data);
4709
4710 // Empty the current queue. This is necessary because idle sockets are
4711 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344712 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524713
4714 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504715 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524716}
4717
[email protected]23e482282013-06-14 16:08:024718TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064719 ScopedVector<UploadElementReader> element_readers;
4720 element_readers.push_back(new UploadBytesElementReader("foo", 3));
[email protected]96c77a72013-09-24 09:49:204721 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:274722
[email protected]1c773ea12009-04-28 19:58:424723 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514724 // Transaction 1: a GET request that succeeds. The socket is recycled
4725 // after use.
4726 request[0].method = "GET";
4727 request[0].url = GURL("http://www.google.com/");
4728 request[0].load_flags = 0;
4729 // Transaction 2: a POST request. Reuses the socket kept alive from
4730 // transaction 1. The first attempts fails when writing the POST data.
4731 // This causes the transaction to retry with a new socket. The second
4732 // attempt succeeds.
4733 request[1].method = "POST";
4734 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274735 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514736 request[1].load_flags = 0;
4737
[email protected]bb88e1d32013-05-03 23:11:074738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514739
4740 // The first socket is used for transaction 1 and the first attempt of
4741 // transaction 2.
4742
4743 // The response of transaction 1.
4744 MockRead data_reads1[] = {
4745 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4746 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064747 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514748 };
4749 // The mock write results of transaction 1 and the first attempt of
4750 // transaction 2.
4751 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064752 MockWrite(SYNCHRONOUS, 64), // GET
4753 MockWrite(SYNCHRONOUS, 93), // POST
4754 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514755 };
[email protected]31a2bfe2010-02-09 08:03:394756 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4757 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514758
4759 // The second socket is used for the second attempt of transaction 2.
4760
4761 // The response of transaction 2.
4762 MockRead data_reads2[] = {
4763 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4764 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064765 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514766 };
4767 // The mock write results of the second attempt of transaction 2.
4768 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064769 MockWrite(SYNCHRONOUS, 93), // POST
4770 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514771 };
[email protected]31a2bfe2010-02-09 08:03:394772 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4773 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514774
[email protected]bb88e1d32013-05-03 23:11:074775 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4776 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514777
4778 const char* kExpectedResponseData[] = {
4779 "hello world", "welcome"
4780 };
4781
4782 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424783 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514785
[email protected]49639fa2011-12-20 23:22:414786 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514787
[email protected]49639fa2011-12-20 23:22:414788 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424789 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514790
4791 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424792 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514793
[email protected]1c773ea12009-04-28 19:58:424794 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504795 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514796
[email protected]90499482013-06-01 00:39:504797 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514798 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4799
4800 std::string response_data;
4801 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424802 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514803 EXPECT_EQ(kExpectedResponseData[i], response_data);
4804 }
4805}
[email protected]f9ee6b52008-11-08 06:46:234806
4807// Test the request-challenge-retry sequence for basic auth when there is
4808// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164809// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024810TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424811 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234812 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294813 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414814 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294815
[email protected]3fe8d2f82013-10-17 08:56:074816 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274817 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:274819
[email protected]a97cca42009-08-14 01:00:294820 // The password contains an escaped character -- for this test to pass it
4821 // will need to be unescaped by HttpNetworkTransaction.
4822 EXPECT_EQ("b%40r", request.url.password());
4823
[email protected]f9ee6b52008-11-08 06:46:234824 MockWrite data_writes1[] = {
4825 MockWrite("GET / HTTP/1.1\r\n"
4826 "Host: www.google.com\r\n"
4827 "Connection: keep-alive\r\n\r\n"),
4828 };
4829
4830 MockRead data_reads1[] = {
4831 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4832 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4833 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064834 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234835 };
4836
[email protected]2262e3a2012-05-22 16:08:164837 // After the challenge above, the transaction will be restarted using the
4838 // identity from the url (foo, b@r) to answer the challenge.
4839 MockWrite data_writes2[] = {
4840 MockWrite("GET / HTTP/1.1\r\n"
4841 "Host: www.google.com\r\n"
4842 "Connection: keep-alive\r\n"
4843 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4844 };
4845
4846 MockRead data_reads2[] = {
4847 MockRead("HTTP/1.0 200 OK\r\n"),
4848 MockRead("Content-Length: 100\r\n\r\n"),
4849 MockRead(SYNCHRONOUS, OK),
4850 };
4851
[email protected]31a2bfe2010-02-09 08:03:394852 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4853 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164854 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4855 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074856 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4857 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234858
[email protected]49639fa2011-12-20 23:22:414859 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414860 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424861 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234862 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424863 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164864 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4865
4866 TestCompletionCallback callback2;
4867 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4868 EXPECT_EQ(ERR_IO_PENDING, rv);
4869 rv = callback2.WaitForResult();
4870 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224871 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4872
[email protected]2262e3a2012-05-22 16:08:164873 const HttpResponseInfo* response = trans->GetResponseInfo();
4874 ASSERT_TRUE(response != NULL);
4875
4876 // There is no challenge info, since the identity in URL worked.
4877 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4878
4879 EXPECT_EQ(100, response->headers->GetContentLength());
4880
4881 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344882 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164883}
4884
4885// Test the request-challenge-retry sequence for basic auth when there is an
4886// incorrect identity in the URL. The identity from the URL should be used only
4887// once.
[email protected]23e482282013-06-14 16:08:024888TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164889 HttpRequestInfo request;
4890 request.method = "GET";
4891 // Note: the URL has a username:password in it. The password "baz" is
4892 // wrong (should be "bar").
4893 request.url = GURL("http://foo:[email protected]/");
4894
4895 request.load_flags = LOAD_NORMAL;
4896
[email protected]3fe8d2f82013-10-17 08:56:074897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:164898 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:074899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2262e3a2012-05-22 16:08:164900
4901 MockWrite data_writes1[] = {
4902 MockWrite("GET / HTTP/1.1\r\n"
4903 "Host: www.google.com\r\n"
4904 "Connection: keep-alive\r\n\r\n"),
4905 };
4906
4907 MockRead data_reads1[] = {
4908 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4909 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4910 MockRead("Content-Length: 10\r\n\r\n"),
4911 MockRead(SYNCHRONOUS, ERR_FAILED),
4912 };
4913
4914 // After the challenge above, the transaction will be restarted using the
4915 // identity from the url (foo, baz) to answer the challenge.
4916 MockWrite data_writes2[] = {
4917 MockWrite("GET / HTTP/1.1\r\n"
4918 "Host: www.google.com\r\n"
4919 "Connection: keep-alive\r\n"
4920 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4921 };
4922
4923 MockRead data_reads2[] = {
4924 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4925 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4926 MockRead("Content-Length: 10\r\n\r\n"),
4927 MockRead(SYNCHRONOUS, ERR_FAILED),
4928 };
4929
4930 // After the challenge above, the transaction will be restarted using the
4931 // identity supplied by the user (foo, bar) to answer the challenge.
4932 MockWrite data_writes3[] = {
4933 MockWrite("GET / HTTP/1.1\r\n"
4934 "Host: www.google.com\r\n"
4935 "Connection: keep-alive\r\n"
4936 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4937 };
4938
4939 MockRead data_reads3[] = {
4940 MockRead("HTTP/1.0 200 OK\r\n"),
4941 MockRead("Content-Length: 100\r\n\r\n"),
4942 MockRead(SYNCHRONOUS, OK),
4943 };
4944
4945 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4946 data_writes1, arraysize(data_writes1));
4947 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4948 data_writes2, arraysize(data_writes2));
4949 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4950 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074951 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4952 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4953 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:164954
4955 TestCompletionCallback callback1;
4956
4957 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4958 EXPECT_EQ(ERR_IO_PENDING, rv);
4959
4960 rv = callback1.WaitForResult();
4961 EXPECT_EQ(OK, rv);
4962
4963 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4964 TestCompletionCallback callback2;
4965 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4966 EXPECT_EQ(ERR_IO_PENDING, rv);
4967 rv = callback2.WaitForResult();
4968 EXPECT_EQ(OK, rv);
4969 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4970
4971 const HttpResponseInfo* response = trans->GetResponseInfo();
4972 ASSERT_TRUE(response != NULL);
4973 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4974
4975 TestCompletionCallback callback3;
4976 rv = trans->RestartWithAuth(
4977 AuthCredentials(kFoo, kBar), callback3.callback());
4978 EXPECT_EQ(ERR_IO_PENDING, rv);
4979 rv = callback3.WaitForResult();
4980 EXPECT_EQ(OK, rv);
4981 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4982
4983 response = trans->GetResponseInfo();
4984 ASSERT_TRUE(response != NULL);
4985
4986 // There is no challenge info, since the identity worked.
4987 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4988
4989 EXPECT_EQ(100, response->headers->GetContentLength());
4990
[email protected]ea9dc9a2009-09-05 00:43:324991 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344992 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:324993}
4994
[email protected]2217aa22013-10-11 03:03:544995
4996// Test the request-challenge-retry sequence for basic auth when there is a
4997// correct identity in the URL, but its use is being suppressed. The identity
4998// from the URL should never be used.
4999TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5000 HttpRequestInfo request;
5001 request.method = "GET";
5002 request.url = GURL("http://foo:[email protected]/");
5003 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5004
[email protected]3fe8d2f82013-10-17 08:56:075005 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545006 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2217aa22013-10-11 03:03:545008
5009 MockWrite data_writes1[] = {
5010 MockWrite("GET / HTTP/1.1\r\n"
5011 "Host: www.google.com\r\n"
5012 "Connection: keep-alive\r\n\r\n"),
5013 };
5014
5015 MockRead data_reads1[] = {
5016 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5017 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5018 MockRead("Content-Length: 10\r\n\r\n"),
5019 MockRead(SYNCHRONOUS, ERR_FAILED),
5020 };
5021
5022 // After the challenge above, the transaction will be restarted using the
5023 // identity supplied by the user, not the one in the URL, to answer the
5024 // challenge.
5025 MockWrite data_writes3[] = {
5026 MockWrite("GET / HTTP/1.1\r\n"
5027 "Host: www.google.com\r\n"
5028 "Connection: keep-alive\r\n"
5029 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5030 };
5031
5032 MockRead data_reads3[] = {
5033 MockRead("HTTP/1.0 200 OK\r\n"),
5034 MockRead("Content-Length: 100\r\n\r\n"),
5035 MockRead(SYNCHRONOUS, OK),
5036 };
5037
5038 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5039 data_writes1, arraysize(data_writes1));
5040 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5041 data_writes3, arraysize(data_writes3));
5042 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5043 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5044
5045 TestCompletionCallback callback1;
5046 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5047 EXPECT_EQ(ERR_IO_PENDING, rv);
5048 rv = callback1.WaitForResult();
5049 EXPECT_EQ(OK, rv);
5050 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5051
5052 const HttpResponseInfo* response = trans->GetResponseInfo();
5053 ASSERT_TRUE(response != NULL);
5054 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5055
5056 TestCompletionCallback callback3;
5057 rv = trans->RestartWithAuth(
5058 AuthCredentials(kFoo, kBar), callback3.callback());
5059 EXPECT_EQ(ERR_IO_PENDING, rv);
5060 rv = callback3.WaitForResult();
5061 EXPECT_EQ(OK, rv);
5062 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5063
5064 response = trans->GetResponseInfo();
5065 ASSERT_TRUE(response != NULL);
5066
5067 // There is no challenge info, since the identity worked.
5068 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5069 EXPECT_EQ(100, response->headers->GetContentLength());
5070
5071 // Empty the current queue.
5072 base::MessageLoop::current()->RunUntilIdle();
5073}
5074
[email protected]f9ee6b52008-11-08 06:46:235075// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025076TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075077 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235078
5079 // Transaction 1: authenticate (foo, bar) on MyRealm1
5080 {
[email protected]1c773ea12009-04-28 19:58:425081 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235082 request.method = "GET";
5083 request.url = GURL("http://www.google.com/x/y/z");
5084 request.load_flags = 0;
5085
[email protected]262eec82013-03-19 21:01:365086 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275088
[email protected]f9ee6b52008-11-08 06:46:235089 MockWrite data_writes1[] = {
5090 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5091 "Host: www.google.com\r\n"
5092 "Connection: keep-alive\r\n\r\n"),
5093 };
5094
5095 MockRead data_reads1[] = {
5096 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5097 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5098 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065099 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235100 };
5101
5102 // Resend with authorization (username=foo, password=bar)
5103 MockWrite data_writes2[] = {
5104 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5105 "Host: www.google.com\r\n"
5106 "Connection: keep-alive\r\n"
5107 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5108 };
5109
5110 // Sever accepts the authorization.
5111 MockRead data_reads2[] = {
5112 MockRead("HTTP/1.0 200 OK\r\n"),
5113 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065114 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235115 };
5116
[email protected]31a2bfe2010-02-09 08:03:395117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5118 data_writes1, arraysize(data_writes1));
5119 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5120 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075121 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5122 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235123
[email protected]49639fa2011-12-20 23:22:415124 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235125
[email protected]49639fa2011-12-20 23:22:415126 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425127 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235128
5129 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425130 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235131
[email protected]1c773ea12009-04-28 19:58:425132 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505133 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045134 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235135
[email protected]49639fa2011-12-20 23:22:415136 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235137
[email protected]49639fa2011-12-20 23:22:415138 rv = trans->RestartWithAuth(
5139 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425140 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235141
5142 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425143 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235144
5145 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505146 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235147 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5148 EXPECT_EQ(100, response->headers->GetContentLength());
5149 }
5150
5151 // ------------------------------------------------------------------------
5152
5153 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5154 {
[email protected]1c773ea12009-04-28 19:58:425155 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235156 request.method = "GET";
5157 // Note that Transaction 1 was at /x/y/z, so this is in the same
5158 // protection space as MyRealm1.
5159 request.url = GURL("http://www.google.com/x/y/a/b");
5160 request.load_flags = 0;
5161
[email protected]262eec82013-03-19 21:01:365162 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275164
[email protected]f9ee6b52008-11-08 06:46:235165 MockWrite data_writes1[] = {
5166 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5167 "Host: www.google.com\r\n"
5168 "Connection: keep-alive\r\n"
5169 // Send preemptive authorization for MyRealm1
5170 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5171 };
5172
5173 // The server didn't like the preemptive authorization, and
5174 // challenges us for a different realm (MyRealm2).
5175 MockRead data_reads1[] = {
5176 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5177 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5178 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065179 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235180 };
5181
5182 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5183 MockWrite data_writes2[] = {
5184 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5185 "Host: www.google.com\r\n"
5186 "Connection: keep-alive\r\n"
5187 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5188 };
5189
5190 // Sever accepts the authorization.
5191 MockRead data_reads2[] = {
5192 MockRead("HTTP/1.0 200 OK\r\n"),
5193 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065194 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235195 };
5196
[email protected]31a2bfe2010-02-09 08:03:395197 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5198 data_writes1, arraysize(data_writes1));
5199 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5200 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075201 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5202 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235203
[email protected]49639fa2011-12-20 23:22:415204 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235205
[email protected]49639fa2011-12-20 23:22:415206 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425207 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235208
5209 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425210 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235211
[email protected]1c773ea12009-04-28 19:58:425212 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505213 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045214 ASSERT_TRUE(response->auth_challenge.get());
5215 EXPECT_FALSE(response->auth_challenge->is_proxy);
5216 EXPECT_EQ("www.google.com:80",
5217 response->auth_challenge->challenger.ToString());
5218 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5219 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235220
[email protected]49639fa2011-12-20 23:22:415221 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235222
[email protected]49639fa2011-12-20 23:22:415223 rv = trans->RestartWithAuth(
5224 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425225 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235226
5227 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425228 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235229
5230 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505231 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235232 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5233 EXPECT_EQ(100, response->headers->GetContentLength());
5234 }
5235
5236 // ------------------------------------------------------------------------
5237
5238 // Transaction 3: Resend a request in MyRealm's protection space --
5239 // succeed with preemptive authorization.
5240 {
[email protected]1c773ea12009-04-28 19:58:425241 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235242 request.method = "GET";
5243 request.url = GURL("http://www.google.com/x/y/z2");
5244 request.load_flags = 0;
5245
[email protected]262eec82013-03-19 21:01:365246 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275248
[email protected]f9ee6b52008-11-08 06:46:235249 MockWrite data_writes1[] = {
5250 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5251 "Host: www.google.com\r\n"
5252 "Connection: keep-alive\r\n"
5253 // The authorization for MyRealm1 gets sent preemptively
5254 // (since the url is in the same protection space)
5255 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5256 };
5257
5258 // Sever accepts the preemptive authorization
5259 MockRead data_reads1[] = {
5260 MockRead("HTTP/1.0 200 OK\r\n"),
5261 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065262 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235263 };
5264
[email protected]31a2bfe2010-02-09 08:03:395265 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5266 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075267 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235268
[email protected]49639fa2011-12-20 23:22:415269 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235270
[email protected]49639fa2011-12-20 23:22:415271 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425272 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235273
5274 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425275 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235276
[email protected]1c773ea12009-04-28 19:58:425277 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505278 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235279
5280 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5281 EXPECT_EQ(100, response->headers->GetContentLength());
5282 }
5283
5284 // ------------------------------------------------------------------------
5285
5286 // Transaction 4: request another URL in MyRealm (however the
5287 // url is not known to belong to the protection space, so no pre-auth).
5288 {
[email protected]1c773ea12009-04-28 19:58:425289 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235290 request.method = "GET";
5291 request.url = GURL("http://www.google.com/x/1");
5292 request.load_flags = 0;
5293
[email protected]262eec82013-03-19 21:01:365294 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275296
[email protected]f9ee6b52008-11-08 06:46:235297 MockWrite data_writes1[] = {
5298 MockWrite("GET /x/1 HTTP/1.1\r\n"
5299 "Host: www.google.com\r\n"
5300 "Connection: keep-alive\r\n\r\n"),
5301 };
5302
5303 MockRead data_reads1[] = {
5304 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5305 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5306 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065307 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235308 };
5309
5310 // Resend with authorization from MyRealm's cache.
5311 MockWrite data_writes2[] = {
5312 MockWrite("GET /x/1 HTTP/1.1\r\n"
5313 "Host: www.google.com\r\n"
5314 "Connection: keep-alive\r\n"
5315 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5316 };
5317
5318 // Sever accepts the authorization.
5319 MockRead data_reads2[] = {
5320 MockRead("HTTP/1.0 200 OK\r\n"),
5321 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065322 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235323 };
5324
[email protected]31a2bfe2010-02-09 08:03:395325 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5326 data_writes1, arraysize(data_writes1));
5327 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5328 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5330 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235331
[email protected]49639fa2011-12-20 23:22:415332 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235333
[email protected]49639fa2011-12-20 23:22:415334 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425335 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235336
5337 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425338 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235339
[email protected]0757e7702009-03-27 04:00:225340 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415341 TestCompletionCallback callback2;
5342 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425343 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225344 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425345 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225346 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5347
[email protected]1c773ea12009-04-28 19:58:425348 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505349 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235350 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5351 EXPECT_EQ(100, response->headers->GetContentLength());
5352 }
5353
5354 // ------------------------------------------------------------------------
5355
5356 // Transaction 5: request a URL in MyRealm, but the server rejects the
5357 // cached identity. Should invalidate and re-prompt.
5358 {
[email protected]1c773ea12009-04-28 19:58:425359 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235360 request.method = "GET";
5361 request.url = GURL("http://www.google.com/p/q/t");
5362 request.load_flags = 0;
5363
[email protected]262eec82013-03-19 21:01:365364 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275366
[email protected]f9ee6b52008-11-08 06:46:235367 MockWrite data_writes1[] = {
5368 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5369 "Host: www.google.com\r\n"
5370 "Connection: keep-alive\r\n\r\n"),
5371 };
5372
5373 MockRead data_reads1[] = {
5374 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5375 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5376 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065377 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235378 };
5379
5380 // Resend with authorization from cache for MyRealm.
5381 MockWrite data_writes2[] = {
5382 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5383 "Host: www.google.com\r\n"
5384 "Connection: keep-alive\r\n"
5385 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5386 };
5387
5388 // Sever rejects the authorization.
5389 MockRead data_reads2[] = {
5390 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5391 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5392 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065393 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235394 };
5395
5396 // At this point we should prompt for new credentials for MyRealm.
5397 // Restart with username=foo3, password=foo4.
5398 MockWrite data_writes3[] = {
5399 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5400 "Host: www.google.com\r\n"
5401 "Connection: keep-alive\r\n"
5402 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5403 };
5404
5405 // Sever accepts the authorization.
5406 MockRead data_reads3[] = {
5407 MockRead("HTTP/1.0 200 OK\r\n"),
5408 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065409 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235410 };
5411
[email protected]31a2bfe2010-02-09 08:03:395412 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5413 data_writes1, arraysize(data_writes1));
5414 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5415 data_writes2, arraysize(data_writes2));
5416 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5417 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075418 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5419 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5420 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235421
[email protected]49639fa2011-12-20 23:22:415422 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235423
[email protected]49639fa2011-12-20 23:22:415424 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425425 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235426
5427 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425428 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235429
[email protected]0757e7702009-03-27 04:00:225430 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415431 TestCompletionCallback callback2;
5432 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425433 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225434 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425435 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225436 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5437
[email protected]1c773ea12009-04-28 19:58:425438 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505439 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045440 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235441
[email protected]49639fa2011-12-20 23:22:415442 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235443
[email protected]49639fa2011-12-20 23:22:415444 rv = trans->RestartWithAuth(
5445 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425446 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235447
[email protected]0757e7702009-03-27 04:00:225448 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425449 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235450
5451 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505452 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235453 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5454 EXPECT_EQ(100, response->headers->GetContentLength());
5455 }
5456}
[email protected]89ceba9a2009-03-21 03:46:065457
[email protected]3c32c5f2010-05-18 15:18:125458// Tests that nonce count increments when multiple auth attempts
5459// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025460TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445461 HttpAuthHandlerDigest::Factory* digest_factory =
5462 new HttpAuthHandlerDigest::Factory();
5463 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5464 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5465 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075466 session_deps_.http_auth_handler_factory.reset(digest_factory);
5467 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125468
5469 // Transaction 1: authenticate (foo, bar) on MyRealm1
5470 {
[email protected]3c32c5f2010-05-18 15:18:125471 HttpRequestInfo request;
5472 request.method = "GET";
5473 request.url = GURL("http://www.google.com/x/y/z");
5474 request.load_flags = 0;
5475
[email protected]262eec82013-03-19 21:01:365476 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505477 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275478
[email protected]3c32c5f2010-05-18 15:18:125479 MockWrite data_writes1[] = {
5480 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5481 "Host: www.google.com\r\n"
5482 "Connection: keep-alive\r\n\r\n"),
5483 };
5484
5485 MockRead data_reads1[] = {
5486 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5487 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5488 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065489 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125490 };
5491
5492 // Resend with authorization (username=foo, password=bar)
5493 MockWrite data_writes2[] = {
5494 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5495 "Host: www.google.com\r\n"
5496 "Connection: keep-alive\r\n"
5497 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5498 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5499 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5500 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5501 };
5502
5503 // Sever accepts the authorization.
5504 MockRead data_reads2[] = {
5505 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065506 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125507 };
5508
5509 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5510 data_writes1, arraysize(data_writes1));
5511 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5512 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075513 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5514 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125515
[email protected]49639fa2011-12-20 23:22:415516 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125517
[email protected]49639fa2011-12-20 23:22:415518 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125519 EXPECT_EQ(ERR_IO_PENDING, rv);
5520
5521 rv = callback1.WaitForResult();
5522 EXPECT_EQ(OK, rv);
5523
5524 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505525 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045526 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125527
[email protected]49639fa2011-12-20 23:22:415528 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125529
[email protected]49639fa2011-12-20 23:22:415530 rv = trans->RestartWithAuth(
5531 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125532 EXPECT_EQ(ERR_IO_PENDING, rv);
5533
5534 rv = callback2.WaitForResult();
5535 EXPECT_EQ(OK, rv);
5536
5537 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505538 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125539 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5540 }
5541
5542 // ------------------------------------------------------------------------
5543
5544 // Transaction 2: Request another resource in digestive's protection space.
5545 // This will preemptively add an Authorization header which should have an
5546 // "nc" value of 2 (as compared to 1 in the first use.
5547 {
[email protected]3c32c5f2010-05-18 15:18:125548 HttpRequestInfo request;
5549 request.method = "GET";
5550 // Note that Transaction 1 was at /x/y/z, so this is in the same
5551 // protection space as digest.
5552 request.url = GURL("http://www.google.com/x/y/a/b");
5553 request.load_flags = 0;
5554
[email protected]262eec82013-03-19 21:01:365555 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275557
[email protected]3c32c5f2010-05-18 15:18:125558 MockWrite data_writes1[] = {
5559 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5560 "Host: www.google.com\r\n"
5561 "Connection: keep-alive\r\n"
5562 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5563 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5564 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5565 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5566 };
5567
5568 // Sever accepts the authorization.
5569 MockRead data_reads1[] = {
5570 MockRead("HTTP/1.0 200 OK\r\n"),
5571 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065572 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125573 };
5574
5575 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5576 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075577 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125578
[email protected]49639fa2011-12-20 23:22:415579 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125580
[email protected]49639fa2011-12-20 23:22:415581 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125582 EXPECT_EQ(ERR_IO_PENDING, rv);
5583
5584 rv = callback1.WaitForResult();
5585 EXPECT_EQ(OK, rv);
5586
5587 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505588 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125589 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5590 }
5591}
5592
[email protected]89ceba9a2009-03-21 03:46:065593// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025594TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065595 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405597 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]89ceba9a2009-03-21 03:46:065599
5600 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065601 trans->read_buf_ = new IOBuffer(15);
5602 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205603 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065604
5605 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145606 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575607 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085608 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575609 response->response_time = base::Time::Now();
5610 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065611
5612 { // Setup state for response_.vary_data
5613 HttpRequestInfo request;
5614 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5615 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275616 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435617 request.extra_headers.SetHeader("Foo", "1");
5618 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505619 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065620 }
5621
5622 // Cause the above state to be reset.
5623 trans->ResetStateForRestart();
5624
5625 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075626 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065627 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205628 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575629 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5630 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045631 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085632 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575633 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065634}
5635
[email protected]bacff652009-03-31 17:50:335636// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025637TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335638 HttpRequestInfo request;
5639 request.method = "GET";
5640 request.url = GURL("https://www.google.com/");
5641 request.load_flags = 0;
5642
[email protected]3fe8d2f82013-10-17 08:56:075643 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275644 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075645 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:275646
[email protected]bacff652009-03-31 17:50:335647 MockWrite data_writes[] = {
5648 MockWrite("GET / HTTP/1.1\r\n"
5649 "Host: www.google.com\r\n"
5650 "Connection: keep-alive\r\n\r\n"),
5651 };
5652
5653 MockRead data_reads[] = {
5654 MockRead("HTTP/1.0 200 OK\r\n"),
5655 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5656 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065657 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335658 };
5659
[email protected]5ecc992a42009-11-11 01:41:595660 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395661 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5662 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065663 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5664 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335665
[email protected]bb88e1d32013-05-03 23:11:075666 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5667 session_deps_.socket_factory->AddSocketDataProvider(&data);
5668 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335670
[email protected]49639fa2011-12-20 23:22:415671 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335672
[email protected]49639fa2011-12-20 23:22:415673 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335674 EXPECT_EQ(ERR_IO_PENDING, rv);
5675
5676 rv = callback.WaitForResult();
5677 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5678
[email protected]49639fa2011-12-20 23:22:415679 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335680 EXPECT_EQ(ERR_IO_PENDING, rv);
5681
5682 rv = callback.WaitForResult();
5683 EXPECT_EQ(OK, rv);
5684
5685 const HttpResponseInfo* response = trans->GetResponseInfo();
5686
[email protected]fe2255a2011-09-20 19:37:505687 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335688 EXPECT_EQ(100, response->headers->GetContentLength());
5689}
5690
5691// Test HTTPS connections to a site with a bad certificate, going through a
5692// proxy
[email protected]23e482282013-06-14 16:08:025693TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075694 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335695
5696 HttpRequestInfo request;
5697 request.method = "GET";
5698 request.url = GURL("https://www.google.com/");
5699 request.load_flags = 0;
5700
5701 MockWrite proxy_writes[] = {
5702 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455703 "Host: www.google.com\r\n"
5704 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335705 };
5706
5707 MockRead proxy_reads[] = {
5708 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065709 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335710 };
5711
5712 MockWrite data_writes[] = {
5713 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455714 "Host: www.google.com\r\n"
5715 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335716 MockWrite("GET / HTTP/1.1\r\n"
5717 "Host: www.google.com\r\n"
5718 "Connection: keep-alive\r\n\r\n"),
5719 };
5720
5721 MockRead data_reads[] = {
5722 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5723 MockRead("HTTP/1.0 200 OK\r\n"),
5724 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5725 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065726 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335727 };
5728
[email protected]31a2bfe2010-02-09 08:03:395729 StaticSocketDataProvider ssl_bad_certificate(
5730 proxy_reads, arraysize(proxy_reads),
5731 proxy_writes, arraysize(proxy_writes));
5732 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5733 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065734 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5735 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335736
[email protected]bb88e1d32013-05-03 23:11:075737 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5738 session_deps_.socket_factory->AddSocketDataProvider(&data);
5739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5740 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335741
[email protected]49639fa2011-12-20 23:22:415742 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335743
5744 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075745 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335746
[email protected]3fe8d2f82013-10-17 08:56:075747 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405748 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]bacff652009-03-31 17:50:335750
[email protected]49639fa2011-12-20 23:22:415751 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335752 EXPECT_EQ(ERR_IO_PENDING, rv);
5753
5754 rv = callback.WaitForResult();
5755 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5756
[email protected]49639fa2011-12-20 23:22:415757 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335758 EXPECT_EQ(ERR_IO_PENDING, rv);
5759
5760 rv = callback.WaitForResult();
5761 EXPECT_EQ(OK, rv);
5762
5763 const HttpResponseInfo* response = trans->GetResponseInfo();
5764
[email protected]fe2255a2011-09-20 19:37:505765 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335766 EXPECT_EQ(100, response->headers->GetContentLength());
5767 }
5768}
5769
[email protected]2df19bb2010-08-25 20:13:465770
5771// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025772TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075773 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205774 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5775 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075776 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465777
5778 HttpRequestInfo request;
5779 request.method = "GET";
5780 request.url = GURL("https://www.google.com/");
5781 request.load_flags = 0;
5782
5783 MockWrite data_writes[] = {
5784 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5785 "Host: www.google.com\r\n"
5786 "Proxy-Connection: keep-alive\r\n\r\n"),
5787 MockWrite("GET / HTTP/1.1\r\n"
5788 "Host: www.google.com\r\n"
5789 "Connection: keep-alive\r\n\r\n"),
5790 };
5791
5792 MockRead data_reads[] = {
5793 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5794 MockRead("HTTP/1.1 200 OK\r\n"),
5795 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5796 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065797 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465798 };
5799
5800 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5801 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065802 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5803 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465804
[email protected]bb88e1d32013-05-03 23:11:075805 session_deps_.socket_factory->AddSocketDataProvider(&data);
5806 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5807 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465808
[email protected]49639fa2011-12-20 23:22:415809 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465810
[email protected]3fe8d2f82013-10-17 08:56:075811 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465812 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:465814
[email protected]49639fa2011-12-20 23:22:415815 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465816 EXPECT_EQ(ERR_IO_PENDING, rv);
5817
5818 rv = callback.WaitForResult();
5819 EXPECT_EQ(OK, rv);
5820 const HttpResponseInfo* response = trans->GetResponseInfo();
5821
[email protected]fe2255a2011-09-20 19:37:505822 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465823
5824 EXPECT_TRUE(response->headers->IsKeepAlive());
5825 EXPECT_EQ(200, response->headers->response_code());
5826 EXPECT_EQ(100, response->headers->GetContentLength());
5827 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205828
5829 LoadTimingInfo load_timing_info;
5830 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5831 TestLoadTimingNotReusedWithPac(load_timing_info,
5832 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465833}
5834
[email protected]511f6f52010-12-17 03:58:295835// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025836TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075837 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205838 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5839 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075840 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295841
5842 HttpRequestInfo request;
5843 request.method = "GET";
5844 request.url = GURL("https://www.google.com/");
5845 request.load_flags = 0;
5846
5847 MockWrite data_writes[] = {
5848 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5849 "Host: www.google.com\r\n"
5850 "Proxy-Connection: keep-alive\r\n\r\n"),
5851 };
5852
5853 MockRead data_reads[] = {
5854 MockRead("HTTP/1.1 302 Redirect\r\n"),
5855 MockRead("Location: http://login.example.com/\r\n"),
5856 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065857 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295858 };
5859
5860 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5861 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065862 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295863
[email protected]bb88e1d32013-05-03 23:11:075864 session_deps_.socket_factory->AddSocketDataProvider(&data);
5865 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295866
[email protected]49639fa2011-12-20 23:22:415867 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295868
[email protected]3fe8d2f82013-10-17 08:56:075869 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295870 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295872
[email protected]49639fa2011-12-20 23:22:415873 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295874 EXPECT_EQ(ERR_IO_PENDING, rv);
5875
5876 rv = callback.WaitForResult();
5877 EXPECT_EQ(OK, rv);
5878 const HttpResponseInfo* response = trans->GetResponseInfo();
5879
[email protected]fe2255a2011-09-20 19:37:505880 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295881
5882 EXPECT_EQ(302, response->headers->response_code());
5883 std::string url;
5884 EXPECT_TRUE(response->headers->IsRedirect(&url));
5885 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205886
5887 // In the case of redirects from proxies, HttpNetworkTransaction returns
5888 // timing for the proxy connection instead of the connection to the host,
5889 // and no send / receive times.
5890 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5891 LoadTimingInfo load_timing_info;
5892 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5893
5894 EXPECT_FALSE(load_timing_info.socket_reused);
5895 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5896
5897 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5898 EXPECT_LE(load_timing_info.proxy_resolve_start,
5899 load_timing_info.proxy_resolve_end);
5900 EXPECT_LE(load_timing_info.proxy_resolve_end,
5901 load_timing_info.connect_timing.connect_start);
5902 ExpectConnectTimingHasTimes(
5903 load_timing_info.connect_timing,
5904 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5905
5906 EXPECT_TRUE(load_timing_info.send_start.is_null());
5907 EXPECT_TRUE(load_timing_info.send_end.is_null());
5908 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:295909}
5910
5911// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025912TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075913 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295914 ProxyService::CreateFixed("https://proxy:70"));
5915
5916 HttpRequestInfo request;
5917 request.method = "GET";
5918 request.url = GURL("https://www.google.com/");
5919 request.load_flags = 0;
5920
[email protected]9075f51c2013-08-15 17:53:545921 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
5922 LOWEST));
[email protected]c10b20852013-05-15 21:29:205923 scoped_ptr<SpdyFrame> goaway(
5924 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295925 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065926 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:125927 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295928 };
5929
5930 static const char* const kExtraHeaders[] = {
5931 "location",
5932 "http://login.example.com/",
5933 };
[email protected]ff98d7f02012-03-22 21:44:195934 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025935 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295936 arraysize(kExtraHeaders)/2, 1));
5937 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065938 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5939 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:295940 };
5941
[email protected]dd54bd82012-07-19 23:44:575942 DelayedSocketData data(
5943 1, // wait for one write to finish before reading.
5944 data_reads, arraysize(data_reads),
5945 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065946 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025947 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295948
[email protected]bb88e1d32013-05-03 23:11:075949 session_deps_.socket_factory->AddSocketDataProvider(&data);
5950 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295951
[email protected]49639fa2011-12-20 23:22:415952 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295953
[email protected]3fe8d2f82013-10-17 08:56:075954 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:295955 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:075956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:295957
[email protected]49639fa2011-12-20 23:22:415958 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295959 EXPECT_EQ(ERR_IO_PENDING, rv);
5960
5961 rv = callback.WaitForResult();
5962 EXPECT_EQ(OK, rv);
5963 const HttpResponseInfo* response = trans->GetResponseInfo();
5964
[email protected]fe2255a2011-09-20 19:37:505965 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295966
5967 EXPECT_EQ(302, response->headers->response_code());
5968 std::string url;
5969 EXPECT_TRUE(response->headers->IsRedirect(&url));
5970 EXPECT_EQ("http://login.example.com/", url);
5971}
5972
[email protected]4eddbc732012-08-09 05:40:175973// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025974TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175975 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075976 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295977 ProxyService::CreateFixed("https://proxy:70"));
5978
5979 HttpRequestInfo request;
5980 request.method = "GET";
5981 request.url = GURL("https://www.google.com/");
5982 request.load_flags = 0;
5983
5984 MockWrite data_writes[] = {
5985 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5986 "Host: www.google.com\r\n"
5987 "Proxy-Connection: keep-alive\r\n\r\n"),
5988 };
5989
5990 MockRead data_reads[] = {
5991 MockRead("HTTP/1.1 404 Not Found\r\n"),
5992 MockRead("Content-Length: 23\r\n\r\n"),
5993 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:065994 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295995 };
5996
5997 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5998 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065999 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296000
[email protected]bb88e1d32013-05-03 23:11:076001 session_deps_.socket_factory->AddSocketDataProvider(&data);
6002 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296003
[email protected]49639fa2011-12-20 23:22:416004 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296005
[email protected]3fe8d2f82013-10-17 08:56:076006 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296007 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296009
[email protected]49639fa2011-12-20 23:22:416010 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296011 EXPECT_EQ(ERR_IO_PENDING, rv);
6012
6013 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176014 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296015
[email protected]4eddbc732012-08-09 05:40:176016 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296017}
6018
[email protected]4eddbc732012-08-09 05:40:176019// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026020TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176021 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076022 session_deps_.proxy_service.reset(
6023 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296024
6025 HttpRequestInfo request;
6026 request.method = "GET";
6027 request.url = GURL("https://www.google.com/");
6028 request.load_flags = 0;
6029
[email protected]9075f51c2013-08-15 17:53:546030 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6031 LOWEST));
[email protected]c10b20852013-05-15 21:29:206032 scoped_ptr<SpdyFrame> rst(
6033 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296034 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066035 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176036 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296037 };
6038
6039 static const char* const kExtraHeaders[] = {
6040 "location",
6041 "http://login.example.com/",
6042 };
[email protected]ff98d7f02012-03-22 21:44:196043 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026044 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296045 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196046 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026047 spdy_util_.ConstructSpdyBodyFrame(
6048 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296049 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066050 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6051 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176052 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296053 };
6054
[email protected]dd54bd82012-07-19 23:44:576055 DelayedSocketData data(
6056 1, // wait for one write to finish before reading.
6057 data_reads, arraysize(data_reads),
6058 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066059 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026060 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296061
[email protected]bb88e1d32013-05-03 23:11:076062 session_deps_.socket_factory->AddSocketDataProvider(&data);
6063 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296064
[email protected]49639fa2011-12-20 23:22:416065 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296066
[email protected]3fe8d2f82013-10-17 08:56:076067 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296068 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]511f6f52010-12-17 03:58:296070
[email protected]49639fa2011-12-20 23:22:416071 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296072 EXPECT_EQ(ERR_IO_PENDING, rv);
6073
6074 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176075 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296076
[email protected]4eddbc732012-08-09 05:40:176077 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296078}
6079
[email protected]0c5fb722012-02-28 11:50:356080// Test the request-challenge-retry sequence for basic auth, through
6081// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026082TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356083 HttpRequestInfo request;
6084 request.method = "GET";
6085 request.url = GURL("https://www.google.com/");
6086 // when the no authentication data flag is set.
6087 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6088
6089 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076090 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206091 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296092 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076093 session_deps_.net_log = log.bound().net_log();
6094 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356095
6096 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:546097 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6098 LOWEST));
[email protected]c10b20852013-05-15 21:29:206099 scoped_ptr<SpdyFrame> rst(
6100 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356101
6102 // After calling trans->RestartWithAuth(), this is the request we should
6103 // be issuing -- the final header line contains the credentials.
6104 const char* const kAuthCredentials[] = {
6105 "proxy-authorization", "Basic Zm9vOmJhcg==",
6106 };
[email protected]fba2dbde2013-05-24 16:09:016107 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:546108 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:356109 // fetch https://www.google.com/ via HTTP
6110 const char get[] = "GET / HTTP/1.1\r\n"
6111 "Host: www.google.com\r\n"
6112 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196113 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026114 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356115
6116 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206117 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216118 CreateMockWrite(*rst, 4, ASYNC),
6119 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206120 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356121 };
6122
6123 // The proxy responds to the connect with a 407, using a persistent
6124 // connection.
6125 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:026126 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
6127 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:356128 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6129 };
6130
[email protected]ff98d7f02012-03-22 21:44:196131 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:236132 spdy_util_.ConstructSpdyControlFrame(NULL,
6133 0,
6134 false,
6135 1,
6136 LOWEST,
6137 SYN_REPLY,
6138 CONTROL_FLAG_NONE,
6139 kAuthChallenge,
6140 arraysize(kAuthChallenge),
6141 0));
[email protected]0c5fb722012-02-28 11:50:356142
[email protected]23e482282013-06-14 16:08:026143 scoped_ptr<SpdyFrame> conn_resp(
6144 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356145 const char resp[] = "HTTP/1.1 200 OK\r\n"
6146 "Content-Length: 5\r\n\r\n";
6147
[email protected]ff98d7f02012-03-22 21:44:196148 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026149 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196150 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026151 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356152 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206153 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6154 CreateMockRead(*conn_resp, 6, ASYNC),
6155 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6156 CreateMockRead(*wrapped_body, 10, ASYNC),
6157 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356158 };
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]0c5fb722012-02-28 11:50:356164 // 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]0c5fb722012-02-28 11:50:356168 // Vanilla SSL to the server
6169 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076170 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356171
6172 TestCompletionCallback callback1;
6173
[email protected]262eec82013-03-19 21:01:366174 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506175 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356176
6177 int rv = trans->Start(&request, callback1.callback(), log.bound());
6178 EXPECT_EQ(ERR_IO_PENDING, rv);
6179
6180 rv = callback1.WaitForResult();
6181 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576182 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356183 log.GetEntries(&entries);
6184 size_t pos = ExpectLogContainsSomewhere(
6185 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6186 NetLog::PHASE_NONE);
6187 ExpectLogContainsSomewhere(
6188 entries, pos,
6189 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6190 NetLog::PHASE_NONE);
6191
6192 const HttpResponseInfo* response = trans->GetResponseInfo();
6193 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506194 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356195 EXPECT_EQ(407, response->headers->response_code());
6196 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6197 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6198 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6199
6200 TestCompletionCallback callback2;
6201
6202 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6203 callback2.callback());
6204 EXPECT_EQ(ERR_IO_PENDING, rv);
6205
6206 rv = callback2.WaitForResult();
6207 EXPECT_EQ(OK, rv);
6208
6209 response = trans->GetResponseInfo();
6210 ASSERT_TRUE(response != NULL);
6211
6212 EXPECT_TRUE(response->headers->IsKeepAlive());
6213 EXPECT_EQ(200, response->headers->response_code());
6214 EXPECT_EQ(5, response->headers->GetContentLength());
6215 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6216
6217 // The password prompt info should not be set.
6218 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6219
[email protected]029c83b62013-01-24 05:28:206220 LoadTimingInfo load_timing_info;
6221 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6222 TestLoadTimingNotReusedWithPac(load_timing_info,
6223 CONNECT_TIMING_HAS_SSL_TIMES);
6224
[email protected]0c5fb722012-02-28 11:50:356225 trans.reset();
6226 session->CloseAllConnections();
6227}
6228
[email protected]7c6f7ba2012-04-03 04:09:296229// Test that an explicitly trusted SPDY proxy can push a resource from an
6230// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026231TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296232 HttpRequestInfo request;
6233 HttpRequestInfo push_request;
6234
[email protected]7c6f7ba2012-04-03 04:09:296235 request.method = "GET";
6236 request.url = GURL("http://www.google.com/");
6237 push_request.method = "GET";
6238 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6239
[email protected]7c6f7ba2012-04-03 04:09:296240 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076241 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206242 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296243 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076244 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506245
6246 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076247 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506248
[email protected]bb88e1d32013-05-03 23:11:076249 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296250
[email protected]cdf8f7e72013-05-23 10:56:466251 scoped_ptr<SpdyFrame> stream1_syn(
6252 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296253
6254 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466255 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296256 };
6257
6258 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026259 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296260
6261 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026262 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296263
6264 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026265 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296266 0,
6267 2,
6268 1,
6269 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436270 const char kPushedData[] = "pushed";
6271 scoped_ptr<SpdyFrame> stream2_body(
6272 spdy_util_.ConstructSpdyBodyFrame(
6273 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296274
6275 MockRead spdy_reads[] = {
6276 CreateMockRead(*stream1_reply, 2, ASYNC),
6277 CreateMockRead(*stream2_syn, 3, ASYNC),
6278 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436279 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296280 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6281 };
6282
[email protected]dd54bd82012-07-19 23:44:576283 OrderedSocketData spdy_data(
6284 spdy_reads, arraysize(spdy_reads),
6285 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076286 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296287 // Negotiate SPDY to the proxy
6288 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026289 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076290 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296291
[email protected]262eec82013-03-19 21:01:366292 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506293 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296294 TestCompletionCallback callback;
6295 int rv = trans->Start(&request, callback.callback(), log.bound());
6296 EXPECT_EQ(ERR_IO_PENDING, rv);
6297
6298 rv = callback.WaitForResult();
6299 EXPECT_EQ(OK, rv);
6300 const HttpResponseInfo* response = trans->GetResponseInfo();
6301
[email protected]262eec82013-03-19 21:01:366302 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506303 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6304 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296305 EXPECT_EQ(ERR_IO_PENDING, rv);
6306
6307 rv = callback.WaitForResult();
6308 EXPECT_EQ(OK, rv);
6309 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6310
6311 ASSERT_TRUE(response != NULL);
6312 EXPECT_TRUE(response->headers->IsKeepAlive());
6313
6314 EXPECT_EQ(200, response->headers->response_code());
6315 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6316
6317 std::string response_data;
6318 rv = ReadTransaction(trans.get(), &response_data);
6319 EXPECT_EQ(OK, rv);
6320 EXPECT_EQ("hello!", response_data);
6321
[email protected]029c83b62013-01-24 05:28:206322 LoadTimingInfo load_timing_info;
6323 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6324 TestLoadTimingNotReusedWithPac(load_timing_info,
6325 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6326
[email protected]7c6f7ba2012-04-03 04:09:296327 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506328 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296329 EXPECT_EQ(200, push_response->headers->response_code());
6330
6331 rv = ReadTransaction(push_trans.get(), &response_data);
6332 EXPECT_EQ(OK, rv);
6333 EXPECT_EQ("pushed", response_data);
6334
[email protected]029c83b62013-01-24 05:28:206335 LoadTimingInfo push_load_timing_info;
6336 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6337 TestLoadTimingReusedWithPac(push_load_timing_info);
6338 // The transactions should share a socket ID, despite being for different
6339 // origins.
6340 EXPECT_EQ(load_timing_info.socket_log_id,
6341 push_load_timing_info.socket_log_id);
6342
[email protected]7c6f7ba2012-04-03 04:09:296343 trans.reset();
6344 push_trans.reset();
6345 session->CloseAllConnections();
6346}
6347
[email protected]8c843192012-04-05 07:15:006348// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026349TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006350 HttpRequestInfo request;
6351
6352 request.method = "GET";
6353 request.url = GURL("http://www.google.com/");
6354
[email protected]8c843192012-04-05 07:15:006355 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076356 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006357 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296358 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076359 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506360
6361 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076362 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506363
[email protected]bb88e1d32013-05-03 23:11:076364 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006365
[email protected]cdf8f7e72013-05-23 10:56:466366 scoped_ptr<SpdyFrame> stream1_syn(
6367 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006368
6369 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206370 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006371
6372 MockWrite spdy_writes[] = {
6373 CreateMockWrite(*stream1_syn, 1, ASYNC),
6374 CreateMockWrite(*push_rst, 4),
6375 };
6376
6377 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026378 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006379
6380 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026381 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006382
6383 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026384 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006385 0,
6386 2,
6387 1,
6388 "https://www.another-origin.com/foo.dat"));
6389
6390 MockRead spdy_reads[] = {
6391 CreateMockRead(*stream1_reply, 2, ASYNC),
6392 CreateMockRead(*stream2_syn, 3, ASYNC),
6393 CreateMockRead(*stream1_body, 5, ASYNC),
6394 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6395 };
6396
[email protected]dd54bd82012-07-19 23:44:576397 OrderedSocketData spdy_data(
6398 spdy_reads, arraysize(spdy_reads),
6399 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076400 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006401 // Negotiate SPDY to the proxy
6402 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026403 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076404 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006405
[email protected]262eec82013-03-19 21:01:366406 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006408 TestCompletionCallback callback;
6409 int rv = trans->Start(&request, callback.callback(), log.bound());
6410 EXPECT_EQ(ERR_IO_PENDING, rv);
6411
6412 rv = callback.WaitForResult();
6413 EXPECT_EQ(OK, rv);
6414 const HttpResponseInfo* response = trans->GetResponseInfo();
6415
6416 ASSERT_TRUE(response != NULL);
6417 EXPECT_TRUE(response->headers->IsKeepAlive());
6418
6419 EXPECT_EQ(200, response->headers->response_code());
6420 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6421
6422 std::string response_data;
6423 rv = ReadTransaction(trans.get(), &response_data);
6424 EXPECT_EQ(OK, rv);
6425 EXPECT_EQ("hello!", response_data);
6426
6427 trans.reset();
6428 session->CloseAllConnections();
6429}
6430
[email protected]2df19bb2010-08-25 20:13:466431// Test HTTPS connections to a site with a bad certificate, going through an
6432// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026433TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076434 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116435 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466436
6437 HttpRequestInfo request;
6438 request.method = "GET";
6439 request.url = GURL("https://www.google.com/");
6440 request.load_flags = 0;
6441
6442 // Attempt to fetch the URL from a server with a bad cert
6443 MockWrite bad_cert_writes[] = {
6444 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6445 "Host: www.google.com\r\n"
6446 "Proxy-Connection: keep-alive\r\n\r\n"),
6447 };
6448
6449 MockRead bad_cert_reads[] = {
6450 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066451 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466452 };
6453
6454 // Attempt to fetch the URL with a good cert
6455 MockWrite good_data_writes[] = {
6456 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6457 "Host: www.google.com\r\n"
6458 "Proxy-Connection: keep-alive\r\n\r\n"),
6459 MockWrite("GET / HTTP/1.1\r\n"
6460 "Host: www.google.com\r\n"
6461 "Connection: keep-alive\r\n\r\n"),
6462 };
6463
6464 MockRead good_cert_reads[] = {
6465 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6466 MockRead("HTTP/1.0 200 OK\r\n"),
6467 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6468 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066469 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466470 };
6471
6472 StaticSocketDataProvider ssl_bad_certificate(
6473 bad_cert_reads, arraysize(bad_cert_reads),
6474 bad_cert_writes, arraysize(bad_cert_writes));
6475 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6476 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066477 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6478 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466479
6480 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6482 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6483 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466484
6485 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076486 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6487 session_deps_.socket_factory->AddSocketDataProvider(&data);
6488 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466489
[email protected]49639fa2011-12-20 23:22:416490 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466491
[email protected]3fe8d2f82013-10-17 08:56:076492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466493 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]2df19bb2010-08-25 20:13:466495
[email protected]49639fa2011-12-20 23:22:416496 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466497 EXPECT_EQ(ERR_IO_PENDING, rv);
6498
6499 rv = callback.WaitForResult();
6500 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6501
[email protected]49639fa2011-12-20 23:22:416502 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466503 EXPECT_EQ(ERR_IO_PENDING, rv);
6504
6505 rv = callback.WaitForResult();
6506 EXPECT_EQ(OK, rv);
6507
6508 const HttpResponseInfo* response = trans->GetResponseInfo();
6509
[email protected]fe2255a2011-09-20 19:37:506510 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466511 EXPECT_EQ(100, response->headers->GetContentLength());
6512}
6513
[email protected]23e482282013-06-14 16:08:026514TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426515 HttpRequestInfo request;
6516 request.method = "GET";
6517 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436518 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6519 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426520
[email protected]3fe8d2f82013-10-17 08:56:076521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276522 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076523 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276524
[email protected]1c773ea12009-04-28 19:58:426525 MockWrite data_writes[] = {
6526 MockWrite("GET / HTTP/1.1\r\n"
6527 "Host: www.google.com\r\n"
6528 "Connection: keep-alive\r\n"
6529 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6530 };
6531
6532 // Lastly, the server responds with the actual content.
6533 MockRead data_reads[] = {
6534 MockRead("HTTP/1.0 200 OK\r\n"),
6535 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6536 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066537 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426538 };
6539
[email protected]31a2bfe2010-02-09 08:03:396540 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6541 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076542 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426543
[email protected]49639fa2011-12-20 23:22:416544 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426545
[email protected]49639fa2011-12-20 23:22:416546 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426547 EXPECT_EQ(ERR_IO_PENDING, rv);
6548
6549 rv = callback.WaitForResult();
6550 EXPECT_EQ(OK, rv);
6551}
6552
[email protected]23e482282013-06-14 16:08:026553TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296554 HttpRequestInfo request;
6555 request.method = "GET";
6556 request.url = GURL("https://www.google.com/");
6557 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6558 "Chromium Ultra Awesome X Edition");
6559
[email protected]bb88e1d32013-05-03 23:11:076560 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076561 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276562 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076563 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276564
[email protected]da81f132010-08-18 23:39:296565 MockWrite data_writes[] = {
6566 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6567 "Host: www.google.com\r\n"
6568 "Proxy-Connection: keep-alive\r\n"
6569 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6570 };
6571 MockRead data_reads[] = {
6572 // Return an error, so the transaction stops here (this test isn't
6573 // interested in the rest).
6574 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6575 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6576 MockRead("Proxy-Connection: close\r\n\r\n"),
6577 };
6578
6579 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6580 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076581 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296582
[email protected]49639fa2011-12-20 23:22:416583 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296584
[email protected]49639fa2011-12-20 23:22:416585 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296586 EXPECT_EQ(ERR_IO_PENDING, rv);
6587
6588 rv = callback.WaitForResult();
6589 EXPECT_EQ(OK, rv);
6590}
6591
[email protected]23e482282013-06-14 16:08:026592TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426593 HttpRequestInfo request;
6594 request.method = "GET";
6595 request.url = GURL("http://www.google.com/");
6596 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166597 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6598 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426599
[email protected]3fe8d2f82013-10-17 08:56:076600 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276601 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076602 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276603
[email protected]1c773ea12009-04-28 19:58:426604 MockWrite data_writes[] = {
6605 MockWrite("GET / HTTP/1.1\r\n"
6606 "Host: www.google.com\r\n"
6607 "Connection: keep-alive\r\n"
6608 "Referer: http://the.previous.site.com/\r\n\r\n"),
6609 };
6610
6611 // Lastly, the server responds with the actual content.
6612 MockRead data_reads[] = {
6613 MockRead("HTTP/1.0 200 OK\r\n"),
6614 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6615 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066616 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426617 };
6618
[email protected]31a2bfe2010-02-09 08:03:396619 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6620 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076621 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426622
[email protected]49639fa2011-12-20 23:22:416623 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426624
[email protected]49639fa2011-12-20 23:22:416625 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426626 EXPECT_EQ(ERR_IO_PENDING, rv);
6627
6628 rv = callback.WaitForResult();
6629 EXPECT_EQ(OK, rv);
6630}
6631
[email protected]23e482282013-06-14 16:08:026632TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426633 HttpRequestInfo request;
6634 request.method = "POST";
6635 request.url = GURL("http://www.google.com/");
6636
[email protected]3fe8d2f82013-10-17 08:56:076637 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276638 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276640
[email protected]1c773ea12009-04-28 19:58:426641 MockWrite data_writes[] = {
6642 MockWrite("POST / HTTP/1.1\r\n"
6643 "Host: www.google.com\r\n"
6644 "Connection: keep-alive\r\n"
6645 "Content-Length: 0\r\n\r\n"),
6646 };
6647
6648 // Lastly, the server responds with the actual content.
6649 MockRead data_reads[] = {
6650 MockRead("HTTP/1.0 200 OK\r\n"),
6651 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6652 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066653 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426654 };
6655
[email protected]31a2bfe2010-02-09 08:03:396656 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6657 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076658 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426659
[email protected]49639fa2011-12-20 23:22:416660 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426661
[email protected]49639fa2011-12-20 23:22:416662 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426663 EXPECT_EQ(ERR_IO_PENDING, rv);
6664
6665 rv = callback.WaitForResult();
6666 EXPECT_EQ(OK, rv);
6667}
6668
[email protected]23e482282013-06-14 16:08:026669TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426670 HttpRequestInfo request;
6671 request.method = "PUT";
6672 request.url = GURL("http://www.google.com/");
6673
[email protected]3fe8d2f82013-10-17 08:56:076674 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276675 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076676 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276677
[email protected]1c773ea12009-04-28 19:58:426678 MockWrite data_writes[] = {
6679 MockWrite("PUT / HTTP/1.1\r\n"
6680 "Host: www.google.com\r\n"
6681 "Connection: keep-alive\r\n"
6682 "Content-Length: 0\r\n\r\n"),
6683 };
6684
6685 // Lastly, the server responds with the actual content.
6686 MockRead data_reads[] = {
6687 MockRead("HTTP/1.0 200 OK\r\n"),
6688 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6689 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066690 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426691 };
6692
[email protected]31a2bfe2010-02-09 08:03:396693 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6694 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076695 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426696
[email protected]49639fa2011-12-20 23:22:416697 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426698
[email protected]49639fa2011-12-20 23:22:416699 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426700 EXPECT_EQ(ERR_IO_PENDING, rv);
6701
6702 rv = callback.WaitForResult();
6703 EXPECT_EQ(OK, rv);
6704}
6705
[email protected]23e482282013-06-14 16:08:026706TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426707 HttpRequestInfo request;
6708 request.method = "HEAD";
6709 request.url = GURL("http://www.google.com/");
6710
[email protected]3fe8d2f82013-10-17 08:56:076711 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276712 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076713 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276714
[email protected]1c773ea12009-04-28 19:58:426715 MockWrite data_writes[] = {
6716 MockWrite("HEAD / HTTP/1.1\r\n"
6717 "Host: www.google.com\r\n"
6718 "Connection: keep-alive\r\n"
6719 "Content-Length: 0\r\n\r\n"),
6720 };
6721
6722 // Lastly, the server responds with the actual content.
6723 MockRead data_reads[] = {
6724 MockRead("HTTP/1.0 200 OK\r\n"),
6725 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6726 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066727 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426728 };
6729
[email protected]31a2bfe2010-02-09 08:03:396730 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6731 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076732 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426733
[email protected]49639fa2011-12-20 23:22:416734 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426735
[email protected]49639fa2011-12-20 23:22:416736 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426737 EXPECT_EQ(ERR_IO_PENDING, rv);
6738
6739 rv = callback.WaitForResult();
6740 EXPECT_EQ(OK, rv);
6741}
6742
[email protected]23e482282013-06-14 16:08:026743TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426744 HttpRequestInfo request;
6745 request.method = "GET";
6746 request.url = GURL("http://www.google.com/");
6747 request.load_flags = LOAD_BYPASS_CACHE;
6748
[email protected]3fe8d2f82013-10-17 08:56:076749 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276750 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276752
[email protected]1c773ea12009-04-28 19:58:426753 MockWrite data_writes[] = {
6754 MockWrite("GET / HTTP/1.1\r\n"
6755 "Host: www.google.com\r\n"
6756 "Connection: keep-alive\r\n"
6757 "Pragma: no-cache\r\n"
6758 "Cache-Control: no-cache\r\n\r\n"),
6759 };
6760
6761 // Lastly, the server responds with the actual content.
6762 MockRead data_reads[] = {
6763 MockRead("HTTP/1.0 200 OK\r\n"),
6764 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6765 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066766 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426767 };
6768
[email protected]31a2bfe2010-02-09 08:03:396769 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6770 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076771 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426772
[email protected]49639fa2011-12-20 23:22:416773 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426774
[email protected]49639fa2011-12-20 23:22:416775 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426776 EXPECT_EQ(ERR_IO_PENDING, rv);
6777
6778 rv = callback.WaitForResult();
6779 EXPECT_EQ(OK, rv);
6780}
6781
[email protected]23e482282013-06-14 16:08:026782TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426783 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426784 HttpRequestInfo request;
6785 request.method = "GET";
6786 request.url = GURL("http://www.google.com/");
6787 request.load_flags = LOAD_VALIDATE_CACHE;
6788
[email protected]3fe8d2f82013-10-17 08:56:076789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276790 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276792
[email protected]1c773ea12009-04-28 19:58:426793 MockWrite data_writes[] = {
6794 MockWrite("GET / HTTP/1.1\r\n"
6795 "Host: www.google.com\r\n"
6796 "Connection: keep-alive\r\n"
6797 "Cache-Control: max-age=0\r\n\r\n"),
6798 };
6799
6800 // Lastly, the server responds with the actual content.
6801 MockRead data_reads[] = {
6802 MockRead("HTTP/1.0 200 OK\r\n"),
6803 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6804 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066805 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426806 };
6807
[email protected]31a2bfe2010-02-09 08:03:396808 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6809 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076810 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426811
[email protected]49639fa2011-12-20 23:22:416812 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426813
[email protected]49639fa2011-12-20 23:22:416814 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426815 EXPECT_EQ(ERR_IO_PENDING, rv);
6816
6817 rv = callback.WaitForResult();
6818 EXPECT_EQ(OK, rv);
6819}
6820
[email protected]23e482282013-06-14 16:08:026821TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426822 HttpRequestInfo request;
6823 request.method = "GET";
6824 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436825 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426826
[email protected]3fe8d2f82013-10-17 08:56:076827 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276828 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076829 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276830
[email protected]1c773ea12009-04-28 19:58:426831 MockWrite data_writes[] = {
6832 MockWrite("GET / HTTP/1.1\r\n"
6833 "Host: www.google.com\r\n"
6834 "Connection: keep-alive\r\n"
6835 "FooHeader: Bar\r\n\r\n"),
6836 };
6837
6838 // Lastly, the server responds with the actual content.
6839 MockRead data_reads[] = {
6840 MockRead("HTTP/1.0 200 OK\r\n"),
6841 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6842 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066843 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426844 };
6845
[email protected]31a2bfe2010-02-09 08:03:396846 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6847 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076848 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426849
[email protected]49639fa2011-12-20 23:22:416850 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426851
[email protected]49639fa2011-12-20 23:22:416852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426853 EXPECT_EQ(ERR_IO_PENDING, rv);
6854
6855 rv = callback.WaitForResult();
6856 EXPECT_EQ(OK, rv);
6857}
6858
[email protected]23e482282013-06-14 16:08:026859TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476860 HttpRequestInfo request;
6861 request.method = "GET";
6862 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436863 request.extra_headers.SetHeader("referer", "www.foo.com");
6864 request.extra_headers.SetHeader("hEllo", "Kitty");
6865 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476866
[email protected]3fe8d2f82013-10-17 08:56:076867 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276868 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076869 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:276870
[email protected]270c6412010-03-29 22:02:476871 MockWrite data_writes[] = {
6872 MockWrite("GET / HTTP/1.1\r\n"
6873 "Host: www.google.com\r\n"
6874 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166875 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476876 "hEllo: Kitty\r\n"
6877 "FoO: bar\r\n\r\n"),
6878 };
6879
6880 // Lastly, the server responds with the actual content.
6881 MockRead data_reads[] = {
6882 MockRead("HTTP/1.0 200 OK\r\n"),
6883 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6884 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066885 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476886 };
6887
6888 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6889 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076890 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:476891
[email protected]49639fa2011-12-20 23:22:416892 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:476893
[email protected]49639fa2011-12-20 23:22:416894 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:476895 EXPECT_EQ(ERR_IO_PENDING, rv);
6896
6897 rv = callback.WaitForResult();
6898 EXPECT_EQ(OK, rv);
6899}
6900
[email protected]23e482282013-06-14 16:08:026901TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276902 HttpRequestInfo request;
6903 request.method = "GET";
6904 request.url = GURL("http://www.google.com/");
6905 request.load_flags = 0;
6906
[email protected]bb88e1d32013-05-03 23:11:076907 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206908 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6909 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076910 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026911
[email protected]3fe8d2f82013-10-17 08:56:076912 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:026913 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:026915
[email protected]3cd17242009-06-23 02:59:026916 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6917 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6918
6919 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066920 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026921 MockWrite("GET / HTTP/1.1\r\n"
6922 "Host: www.google.com\r\n"
6923 "Connection: keep-alive\r\n\r\n")
6924 };
6925
6926 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066927 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:026928 MockRead("HTTP/1.0 200 OK\r\n"),
6929 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6930 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066931 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026932 };
6933
[email protected]31a2bfe2010-02-09 08:03:396934 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6935 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076936 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026937
[email protected]49639fa2011-12-20 23:22:416938 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026939
[email protected]49639fa2011-12-20 23:22:416940 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026941 EXPECT_EQ(ERR_IO_PENDING, rv);
6942
6943 rv = callback.WaitForResult();
6944 EXPECT_EQ(OK, rv);
6945
6946 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506947 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026948
[email protected]029c83b62013-01-24 05:28:206949 LoadTimingInfo load_timing_info;
6950 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6951 TestLoadTimingNotReusedWithPac(load_timing_info,
6952 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6953
[email protected]3cd17242009-06-23 02:59:026954 std::string response_text;
6955 rv = ReadTransaction(trans.get(), &response_text);
6956 EXPECT_EQ(OK, rv);
6957 EXPECT_EQ("Payload", response_text);
6958}
6959
[email protected]23e482282013-06-14 16:08:026960TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276961 HttpRequestInfo request;
6962 request.method = "GET";
6963 request.url = GURL("https://www.google.com/");
6964 request.load_flags = 0;
6965
[email protected]bb88e1d32013-05-03 23:11:076966 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206967 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6968 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076969 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026970
[email protected]3fe8d2f82013-10-17 08:56:076971 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:026972 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:076973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3cd17242009-06-23 02:59:026974
[email protected]3cd17242009-06-23 02:59:026975 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6976 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6977
6978 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066979 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:356980 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026981 MockWrite("GET / HTTP/1.1\r\n"
6982 "Host: www.google.com\r\n"
6983 "Connection: keep-alive\r\n\r\n")
6984 };
6985
6986 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016987 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6988 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:356989 MockRead("HTTP/1.0 200 OK\r\n"),
6990 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6991 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066992 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356993 };
6994
[email protected]31a2bfe2010-02-09 08:03:396995 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6996 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076997 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356998
[email protected]8ddf8322012-02-23 18:08:066999 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077000 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357001
[email protected]49639fa2011-12-20 23:22:417002 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357003
[email protected]49639fa2011-12-20 23:22:417004 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357005 EXPECT_EQ(ERR_IO_PENDING, rv);
7006
7007 rv = callback.WaitForResult();
7008 EXPECT_EQ(OK, rv);
7009
[email protected]029c83b62013-01-24 05:28:207010 LoadTimingInfo load_timing_info;
7011 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7012 TestLoadTimingNotReusedWithPac(load_timing_info,
7013 CONNECT_TIMING_HAS_SSL_TIMES);
7014
[email protected]e0c27be2009-07-15 13:09:357015 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507016 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357017
7018 std::string response_text;
7019 rv = ReadTransaction(trans.get(), &response_text);
7020 EXPECT_EQ(OK, rv);
7021 EXPECT_EQ("Payload", response_text);
7022}
7023
[email protected]23e482282013-06-14 16:08:027024TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207025 HttpRequestInfo request;
7026 request.method = "GET";
7027 request.url = GURL("http://www.google.com/");
7028 request.load_flags = 0;
7029
[email protected]bb88e1d32013-05-03 23:11:077030 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207031 ProxyService::CreateFixed("socks4://myproxy:1080"));
7032 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077033 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207034
[email protected]3fe8d2f82013-10-17 08:56:077035 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207036 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077037 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]029c83b62013-01-24 05:28:207038
7039 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7040 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7041
7042 MockWrite data_writes[] = {
7043 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7044 MockWrite("GET / HTTP/1.1\r\n"
7045 "Host: www.google.com\r\n"
7046 "Connection: keep-alive\r\n\r\n")
7047 };
7048
7049 MockRead data_reads[] = {
7050 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7051 MockRead("HTTP/1.0 200 OK\r\n"),
7052 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7053 MockRead("Payload"),
7054 MockRead(SYNCHRONOUS, OK)
7055 };
7056
7057 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7058 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077059 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207060
7061 TestCompletionCallback callback;
7062
7063 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7064 EXPECT_EQ(ERR_IO_PENDING, rv);
7065
7066 rv = callback.WaitForResult();
7067 EXPECT_EQ(OK, rv);
7068
7069 const HttpResponseInfo* response = trans->GetResponseInfo();
7070 ASSERT_TRUE(response != NULL);
7071
7072 LoadTimingInfo load_timing_info;
7073 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7074 TestLoadTimingNotReused(load_timing_info,
7075 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7076
7077 std::string response_text;
7078 rv = ReadTransaction(trans.get(), &response_text);
7079 EXPECT_EQ(OK, rv);
7080 EXPECT_EQ("Payload", response_text);
7081}
7082
[email protected]23e482282013-06-14 16:08:027083TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277084 HttpRequestInfo request;
7085 request.method = "GET";
7086 request.url = GURL("http://www.google.com/");
7087 request.load_flags = 0;
7088
[email protected]bb88e1d32013-05-03 23:11:077089 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207090 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7091 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077092 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357093
[email protected]3fe8d2f82013-10-17 08:56:077094 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357095 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077096 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357097
[email protected]e0c27be2009-07-15 13:09:357098 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7099 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377100 const char kSOCKS5OkRequest[] = {
7101 0x05, // Version
7102 0x01, // Command (CONNECT)
7103 0x00, // Reserved.
7104 0x03, // Address type (DOMAINNAME).
7105 0x0E, // Length of domain (14)
7106 // Domain string:
7107 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7108 0x00, 0x50, // 16-bit port (80)
7109 };
[email protected]e0c27be2009-07-15 13:09:357110 const char kSOCKS5OkResponse[] =
7111 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7112
7113 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067114 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7115 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357116 MockWrite("GET / HTTP/1.1\r\n"
7117 "Host: www.google.com\r\n"
7118 "Connection: keep-alive\r\n\r\n")
7119 };
7120
7121 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017122 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7123 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357124 MockRead("HTTP/1.0 200 OK\r\n"),
7125 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7126 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067127 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357128 };
7129
[email protected]31a2bfe2010-02-09 08:03:397130 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7131 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077132 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357133
[email protected]49639fa2011-12-20 23:22:417134 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357135
[email protected]49639fa2011-12-20 23:22:417136 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357137 EXPECT_EQ(ERR_IO_PENDING, rv);
7138
7139 rv = callback.WaitForResult();
7140 EXPECT_EQ(OK, rv);
7141
7142 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507143 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357144
[email protected]029c83b62013-01-24 05:28:207145 LoadTimingInfo load_timing_info;
7146 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7147 TestLoadTimingNotReusedWithPac(load_timing_info,
7148 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7149
[email protected]e0c27be2009-07-15 13:09:357150 std::string response_text;
7151 rv = ReadTransaction(trans.get(), &response_text);
7152 EXPECT_EQ(OK, rv);
7153 EXPECT_EQ("Payload", response_text);
7154}
7155
[email protected]23e482282013-06-14 16:08:027156TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277157 HttpRequestInfo request;
7158 request.method = "GET";
7159 request.url = GURL("https://www.google.com/");
7160 request.load_flags = 0;
7161
[email protected]bb88e1d32013-05-03 23:11:077162 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207163 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7164 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077165 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357166
[email protected]3fe8d2f82013-10-17 08:56:077167 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357168 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]e0c27be2009-07-15 13:09:357170
[email protected]e0c27be2009-07-15 13:09:357171 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7172 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377173 const unsigned char kSOCKS5OkRequest[] = {
7174 0x05, // Version
7175 0x01, // Command (CONNECT)
7176 0x00, // Reserved.
7177 0x03, // Address type (DOMAINNAME).
7178 0x0E, // Length of domain (14)
7179 // Domain string:
7180 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7181 0x01, 0xBB, // 16-bit port (443)
7182 };
7183
[email protected]e0c27be2009-07-15 13:09:357184 const char kSOCKS5OkResponse[] =
7185 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7186
7187 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067188 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7189 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357190 arraysize(kSOCKS5OkRequest)),
7191 MockWrite("GET / HTTP/1.1\r\n"
7192 "Host: www.google.com\r\n"
7193 "Connection: keep-alive\r\n\r\n")
7194 };
7195
7196 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017197 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7198 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027199 MockRead("HTTP/1.0 200 OK\r\n"),
7200 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7201 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067202 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027203 };
7204
[email protected]31a2bfe2010-02-09 08:03:397205 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7206 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077207 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027208
[email protected]8ddf8322012-02-23 18:08:067209 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077210 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027211
[email protected]49639fa2011-12-20 23:22:417212 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027213
[email protected]49639fa2011-12-20 23:22:417214 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027215 EXPECT_EQ(ERR_IO_PENDING, rv);
7216
7217 rv = callback.WaitForResult();
7218 EXPECT_EQ(OK, rv);
7219
7220 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507221 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027222
[email protected]029c83b62013-01-24 05:28:207223 LoadTimingInfo load_timing_info;
7224 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7225 TestLoadTimingNotReusedWithPac(load_timing_info,
7226 CONNECT_TIMING_HAS_SSL_TIMES);
7227
[email protected]3cd17242009-06-23 02:59:027228 std::string response_text;
7229 rv = ReadTransaction(trans.get(), &response_text);
7230 EXPECT_EQ(OK, rv);
7231 EXPECT_EQ("Payload", response_text);
7232}
7233
[email protected]448d4ca52012-03-04 04:12:237234namespace {
7235
[email protected]04e5be32009-06-26 20:00:317236// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067237
7238struct GroupNameTest {
7239 std::string proxy_server;
7240 std::string url;
7241 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187242 bool ssl;
[email protected]2d731a32010-04-29 01:04:067243};
7244
7245scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437246 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077247 SpdySessionDependencies* session_deps_) {
7248 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067249
[email protected]30d4c022013-07-18 22:58:167250 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537251 session->http_server_properties();
7252 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067253 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437254 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067255
7256 return session;
7257}
7258
7259int GroupNameTransactionHelper(
7260 const std::string& url,
7261 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067262 HttpRequestInfo request;
7263 request.method = "GET";
7264 request.url = GURL(url);
7265 request.load_flags = 0;
7266
[email protected]262eec82013-03-19 21:01:367267 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277269
[email protected]49639fa2011-12-20 23:22:417270 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067271
7272 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417273 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067274}
7275
[email protected]448d4ca52012-03-04 04:12:237276} // namespace
7277
[email protected]23e482282013-06-14 16:08:027278TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067279 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317280 {
[email protected]2d731a32010-04-29 01:04:067281 "", // unused
[email protected]04e5be32009-06-26 20:00:317282 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547283 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187284 false,
[email protected]2ff8b312010-04-26 22:20:547285 },
7286 {
[email protected]2d731a32010-04-29 01:04:067287 "", // unused
[email protected]2ff8b312010-04-26 22:20:547288 "http://[2001:1418:13:1::25]/direct",
7289 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187290 false,
[email protected]04e5be32009-06-26 20:00:317291 },
[email protected]04e5be32009-06-26 20:00:317292
7293 // SSL Tests
7294 {
[email protected]2d731a32010-04-29 01:04:067295 "", // unused
[email protected]04e5be32009-06-26 20:00:317296 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027297 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187298 true,
[email protected]04e5be32009-06-26 20:00:317299 },
7300 {
[email protected]2d731a32010-04-29 01:04:067301 "", // unused
7302 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027303 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187304 true,
[email protected]04e5be32009-06-26 20:00:317305 },
7306 {
[email protected]2d731a32010-04-29 01:04:067307 "", // unused
[email protected]2ff8b312010-04-26 22:20:547308 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027309 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187310 true,
[email protected]2ff8b312010-04-26 22:20:547311 },
[email protected]2d731a32010-04-29 01:04:067312 };
[email protected]2ff8b312010-04-26 22:20:547313
[email protected]8e6441ca2010-08-19 05:56:387314 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067315
7316 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077317 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027318 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067319 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437320 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067321
7322 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287323 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7324 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137325 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347326 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447327 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7328 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027329 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7330 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447331 peer.SetClientSocketPoolManager(
7332 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067333
7334 EXPECT_EQ(ERR_IO_PENDING,
7335 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187336 if (tests[i].ssl)
7337 EXPECT_EQ(tests[i].expected_group_name,
7338 ssl_conn_pool->last_group_name_received());
7339 else
7340 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287341 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067342 }
7343
[email protected]2d731a32010-04-29 01:04:067344}
7345
[email protected]23e482282013-06-14 16:08:027346TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067347 const GroupNameTest tests[] = {
7348 {
7349 "http_proxy",
7350 "http://www.google.com/http_proxy_normal",
7351 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187352 false,
[email protected]2d731a32010-04-29 01:04:067353 },
7354
7355 // SSL Tests
7356 {
7357 "http_proxy",
7358 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027359 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187360 true,
[email protected]2d731a32010-04-29 01:04:067361 },
[email protected]af3490e2010-10-16 21:02:297362
[email protected]9faeded92010-04-29 20:03:057363 {
7364 "http_proxy",
7365 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027366 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187367 true,
[email protected]9faeded92010-04-29 20:03:057368 },
[email protected]45499252013-01-23 17:12:567369
7370 {
7371 "http_proxy",
7372 "ftp://ftp.google.com/http_proxy_normal",
7373 "ftp/ftp.google.com:21",
7374 false,
7375 },
[email protected]2d731a32010-04-29 01:04:067376 };
7377
[email protected]8e6441ca2010-08-19 05:56:387378 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067379
7380 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077381 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027382 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067383 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437384 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067385
7386 HttpNetworkSessionPeer peer(session);
7387
[email protected]e60e47a2010-07-14 03:37:187388 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137389 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347390 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137391 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347392 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027393
[email protected]831e4a32013-11-14 02:14:447394 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7395 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027396 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7397 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447398 peer.SetClientSocketPoolManager(
7399 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]2d731a32010-04-29 01:04:067400
7401 EXPECT_EQ(ERR_IO_PENDING,
7402 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187403 if (tests[i].ssl)
7404 EXPECT_EQ(tests[i].expected_group_name,
7405 ssl_conn_pool->last_group_name_received());
7406 else
7407 EXPECT_EQ(tests[i].expected_group_name,
7408 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067409 }
[email protected]2d731a32010-04-29 01:04:067410}
7411
[email protected]23e482282013-06-14 16:08:027412TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067413 const GroupNameTest tests[] = {
7414 {
7415 "socks4://socks_proxy:1080",
7416 "http://www.google.com/socks4_direct",
7417 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187418 false,
[email protected]2d731a32010-04-29 01:04:067419 },
7420 {
7421 "socks5://socks_proxy:1080",
7422 "http://www.google.com/socks5_direct",
7423 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187424 false,
[email protected]2d731a32010-04-29 01:04:067425 },
7426
7427 // SSL Tests
7428 {
7429 "socks4://socks_proxy:1080",
7430 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027431 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187432 true,
[email protected]2d731a32010-04-29 01:04:067433 },
7434 {
7435 "socks5://socks_proxy:1080",
7436 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027437 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187438 true,
[email protected]2d731a32010-04-29 01:04:067439 },
[email protected]af3490e2010-10-16 21:02:297440
[email protected]9faeded92010-04-29 20:03:057441 {
7442 "socks4://socks_proxy:1080",
7443 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027444 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187445 true,
[email protected]9faeded92010-04-29 20:03:057446 },
[email protected]04e5be32009-06-26 20:00:317447 };
7448
[email protected]8e6441ca2010-08-19 05:56:387449 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547450
[email protected]04e5be32009-06-26 20:00:317451 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077452 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027453 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067454 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437455 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027456
[email protected]2d731a32010-04-29 01:04:067457 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317458
[email protected]e60e47a2010-07-14 03:37:187459 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137460 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347461 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137462 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347463 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027464
[email protected]831e4a32013-11-14 02:14:447465 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7466 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027467 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7468 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
[email protected]831e4a32013-11-14 02:14:447469 peer.SetClientSocketPoolManager(
7470 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]04e5be32009-06-26 20:00:317471
[email protected]262eec82013-03-19 21:01:367472 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507473 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317474
[email protected]2d731a32010-04-29 01:04:067475 EXPECT_EQ(ERR_IO_PENDING,
7476 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187477 if (tests[i].ssl)
7478 EXPECT_EQ(tests[i].expected_group_name,
7479 ssl_conn_pool->last_group_name_received());
7480 else
7481 EXPECT_EQ(tests[i].expected_group_name,
7482 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317483 }
7484}
7485
[email protected]23e482282013-06-14 16:08:027486TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277487 HttpRequestInfo request;
7488 request.method = "GET";
7489 request.url = GURL("http://www.google.com/");
7490
[email protected]bb88e1d32013-05-03 23:11:077491 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007492 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327493
[email protected]69719062010-01-05 20:09:217494 // This simulates failure resolving all hostnames; that means we will fail
7495 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077496 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327497
[email protected]3fe8d2f82013-10-17 08:56:077498 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257499 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077500 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]9172a982009-06-06 00:30:257501
[email protected]49639fa2011-12-20 23:22:417502 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257503
[email protected]49639fa2011-12-20 23:22:417504 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257505 EXPECT_EQ(ERR_IO_PENDING, rv);
7506
[email protected]9172a982009-06-06 00:30:257507 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017508 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257509}
7510
[email protected]685af592010-05-11 19:31:247511// Base test to make sure that when the load flags for a request specify to
7512// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027513void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077514 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277515 // Issue a request, asking to bypass the cache(s).
7516 HttpRequestInfo request;
7517 request.method = "GET";
7518 request.load_flags = load_flags;
7519 request.url = GURL("http://www.google.com/");
7520
[email protected]a2c2fb92009-07-18 07:31:047521 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077522 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327523
[email protected]3fe8d2f82013-10-17 08:56:077524 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7525 scoped_ptr<HttpTransaction> trans(
7526 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]3b9cca42009-06-16 01:08:287527
[email protected]6e78dfb2011-07-28 21:34:477528 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287529 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297530 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077531 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107532 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7533 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417534 &addrlist,
7535 callback.callback(),
7536 NULL,
7537 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477538 EXPECT_EQ(ERR_IO_PENDING, rv);
7539 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287540 EXPECT_EQ(OK, rv);
7541
7542 // Verify that it was added to host cache, by doing a subsequent async lookup
7543 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077544 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107545 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7546 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417547 &addrlist,
7548 callback.callback(),
7549 NULL,
7550 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327551 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287552
7553 // Inject a failure the next time that "www.google.com" is resolved. This way
7554 // we can tell if the next lookup hit the cache, or the "network".
7555 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077556 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287557
7558 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7559 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067560 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397561 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077562 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287563
[email protected]3b9cca42009-06-16 01:08:287564 // Run the request.
[email protected]49639fa2011-12-20 23:22:417565 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287566 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417567 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287568
7569 // If we bypassed the cache, we would have gotten a failure while resolving
7570 // "www.google.com".
7571 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7572}
7573
[email protected]685af592010-05-11 19:31:247574// There are multiple load flags that should trigger the host cache bypass.
7575// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027576TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247577 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7578}
7579
[email protected]23e482282013-06-14 16:08:027580TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247581 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7582}
7583
[email protected]23e482282013-06-14 16:08:027584TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247585 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7586}
7587
[email protected]0877e3d2009-10-17 22:29:577588// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027589TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577590 HttpRequestInfo request;
7591 request.method = "GET";
7592 request.url = GURL("http://www.foo.com/");
7593 request.load_flags = 0;
7594
7595 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067596 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577597 };
[email protected]31a2bfe2010-02-09 08:03:397598 StaticSocketDataProvider data(NULL, 0,
7599 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077600 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077601 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577602
[email protected]49639fa2011-12-20 23:22:417603 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577604
7605 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577607
[email protected]49639fa2011-12-20 23:22:417608 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577609 EXPECT_EQ(ERR_IO_PENDING, rv);
7610
7611 rv = callback.WaitForResult();
7612 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7613}
7614
7615// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027616TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577617 HttpRequestInfo request;
7618 request.method = "GET";
7619 request.url = GURL("http://www.foo.com/");
7620 request.load_flags = 0;
7621
7622 MockRead data_reads[] = {
7623 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067624 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577625 };
7626
[email protected]31a2bfe2010-02-09 08:03:397627 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077628 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077629 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577630
[email protected]49639fa2011-12-20 23:22:417631 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577632
7633 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077634 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577635
[email protected]49639fa2011-12-20 23:22:417636 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577637 EXPECT_EQ(ERR_IO_PENDING, rv);
7638
7639 rv = callback.WaitForResult();
7640 EXPECT_EQ(OK, rv);
7641
7642 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507643 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577644
[email protected]90499482013-06-01 00:39:507645 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577646 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7647
7648 std::string response_data;
7649 rv = ReadTransaction(trans.get(), &response_data);
7650 EXPECT_EQ(OK, rv);
7651 EXPECT_EQ("", response_data);
7652}
7653
7654// Make sure that a dropped connection while draining the body for auth
7655// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027656TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577657 HttpRequestInfo request;
7658 request.method = "GET";
7659 request.url = GURL("http://www.google.com/");
7660 request.load_flags = 0;
7661
7662 MockWrite data_writes1[] = {
7663 MockWrite("GET / HTTP/1.1\r\n"
7664 "Host: www.google.com\r\n"
7665 "Connection: keep-alive\r\n\r\n"),
7666 };
7667
7668 MockRead data_reads1[] = {
7669 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7670 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7671 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7672 MockRead("Content-Length: 14\r\n\r\n"),
7673 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067674 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577675 };
7676
[email protected]31a2bfe2010-02-09 08:03:397677 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7678 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577680
7681 // After calling trans->RestartWithAuth(), this is the request we should
7682 // be issuing -- the final header line contains the credentials.
7683 MockWrite data_writes2[] = {
7684 MockWrite("GET / HTTP/1.1\r\n"
7685 "Host: www.google.com\r\n"
7686 "Connection: keep-alive\r\n"
7687 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7688 };
7689
7690 // Lastly, the server responds with the actual content.
7691 MockRead data_reads2[] = {
7692 MockRead("HTTP/1.1 200 OK\r\n"),
7693 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7694 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067695 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577696 };
7697
[email protected]31a2bfe2010-02-09 08:03:397698 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7699 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077700 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577702
[email protected]49639fa2011-12-20 23:22:417703 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577704
[email protected]262eec82013-03-19 21:01:367705 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507707
[email protected]49639fa2011-12-20 23:22:417708 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577709 EXPECT_EQ(ERR_IO_PENDING, rv);
7710
7711 rv = callback1.WaitForResult();
7712 EXPECT_EQ(OK, rv);
7713
7714 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507715 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047716 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577717
[email protected]49639fa2011-12-20 23:22:417718 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577719
[email protected]49639fa2011-12-20 23:22:417720 rv = trans->RestartWithAuth(
7721 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577722 EXPECT_EQ(ERR_IO_PENDING, rv);
7723
7724 rv = callback2.WaitForResult();
7725 EXPECT_EQ(OK, rv);
7726
7727 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507728 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577729 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7730 EXPECT_EQ(100, response->headers->GetContentLength());
7731}
7732
7733// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027734TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077735 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577736
7737 HttpRequestInfo request;
7738 request.method = "GET";
7739 request.url = GURL("https://www.google.com/");
7740 request.load_flags = 0;
7741
7742 MockRead proxy_reads[] = {
7743 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067744 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577745 };
7746
[email protected]31a2bfe2010-02-09 08:03:397747 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067748 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577749
[email protected]bb88e1d32013-05-03 23:11:077750 session_deps_.socket_factory->AddSocketDataProvider(&data);
7751 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577752
[email protected]49639fa2011-12-20 23:22:417753 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577754
[email protected]bb88e1d32013-05-03 23:11:077755 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577756
[email protected]3fe8d2f82013-10-17 08:56:077757 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577758 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077759 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0877e3d2009-10-17 22:29:577760
[email protected]49639fa2011-12-20 23:22:417761 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577762 EXPECT_EQ(ERR_IO_PENDING, rv);
7763
7764 rv = callback.WaitForResult();
7765 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7766}
7767
[email protected]23e482282013-06-14 16:08:027768TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467769 HttpRequestInfo request;
7770 request.method = "GET";
7771 request.url = GURL("http://www.google.com/");
7772 request.load_flags = 0;
7773
[email protected]3fe8d2f82013-10-17 08:56:077774 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277775 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:277777
[email protected]e22e1362009-11-23 21:31:127778 MockRead data_reads[] = {
7779 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067780 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127781 };
[email protected]9492e4a2010-02-24 00:58:467782
7783 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077784 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467785
[email protected]49639fa2011-12-20 23:22:417786 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467787
[email protected]49639fa2011-12-20 23:22:417788 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467789 EXPECT_EQ(ERR_IO_PENDING, rv);
7790
7791 EXPECT_EQ(OK, callback.WaitForResult());
7792
7793 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507794 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467795
[email protected]90499482013-06-01 00:39:507796 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467797 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7798
7799 std::string response_data;
7800 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237801 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127802}
7803
[email protected]23e482282013-06-14 16:08:027804TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157805 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:527806 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:337807 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217808 UploadFileElementReader::ScopedOverridingContentLengthForTests
7809 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337810
[email protected]b2d26cfd2012-12-11 10:36:067811 ScopedVector<UploadElementReader> element_readers;
7812 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367813 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7814 temp_file_path,
7815 0,
7816 kuint64max,
7817 base::Time()));
[email protected]96c77a72013-09-24 09:49:207818 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277819
7820 HttpRequestInfo request;
7821 request.method = "POST";
7822 request.url = GURL("http://www.google.com/upload");
7823 request.upload_data_stream = &upload_data_stream;
7824 request.load_flags = 0;
7825
[email protected]3fe8d2f82013-10-17 08:56:077826 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277827 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077828 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]95d88ffe2010-02-04 21:25:337829
7830 MockRead data_reads[] = {
7831 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7832 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067833 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337834 };
[email protected]31a2bfe2010-02-09 08:03:397835 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077836 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337837
[email protected]49639fa2011-12-20 23:22:417838 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337839
[email protected]49639fa2011-12-20 23:22:417840 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337841 EXPECT_EQ(ERR_IO_PENDING, rv);
7842
7843 rv = callback.WaitForResult();
7844 EXPECT_EQ(OK, rv);
7845
7846 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507847 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337848
[email protected]90499482013-06-01 00:39:507849 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337850 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7851
7852 std::string response_data;
7853 rv = ReadTransaction(trans.get(), &response_data);
7854 EXPECT_EQ(OK, rv);
7855 EXPECT_EQ("hello world", response_data);
7856
[email protected]dd3aa792013-07-16 19:10:237857 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:337858}
7859
[email protected]23e482282013-06-14 16:08:027860TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157861 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:527862 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:367863 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:307864 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:367865 temp_file_content.length()));
7866 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7867
[email protected]b2d26cfd2012-12-11 10:36:067868 ScopedVector<UploadElementReader> element_readers;
7869 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367870 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7871 temp_file,
7872 0,
7873 kuint64max,
7874 base::Time()));
[email protected]96c77a72013-09-24 09:49:207875 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:277876
7877 HttpRequestInfo request;
7878 request.method = "POST";
7879 request.url = GURL("http://www.google.com/upload");
7880 request.upload_data_stream = &upload_data_stream;
7881 request.load_flags = 0;
7882
[email protected]999dd8c2013-11-12 06:45:547883 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:077884 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:277885 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]6624b4622010-03-29 19:58:367887
[email protected]999dd8c2013-11-12 06:45:547888 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077889 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367890
[email protected]49639fa2011-12-20 23:22:417891 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:367892
[email protected]49639fa2011-12-20 23:22:417893 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367894 EXPECT_EQ(ERR_IO_PENDING, rv);
7895
7896 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:547897 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:367898
7899 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:547900 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:367901
[email protected]dd3aa792013-07-16 19:10:237902 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367903}
7904
[email protected]02cad5d2013-10-02 08:14:037905TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
7906 class FakeUploadElementReader : public UploadElementReader {
7907 public:
7908 FakeUploadElementReader() {}
7909 virtual ~FakeUploadElementReader() {}
7910
7911 const CompletionCallback& callback() const { return callback_; }
7912
7913 // UploadElementReader overrides:
7914 virtual int Init(const CompletionCallback& callback) OVERRIDE {
7915 callback_ = callback;
7916 return ERR_IO_PENDING;
7917 }
7918 virtual uint64 GetContentLength() const OVERRIDE { return 0; }
7919 virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
7920 virtual int Read(IOBuffer* buf,
7921 int buf_length,
7922 const CompletionCallback& callback) OVERRIDE {
7923 return ERR_FAILED;
7924 }
7925
7926 private:
7927 CompletionCallback callback_;
7928 };
7929
7930 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
7931 ScopedVector<UploadElementReader> element_readers;
7932 element_readers.push_back(fake_reader);
7933 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
7934
7935 HttpRequestInfo request;
7936 request.method = "POST";
7937 request.url = GURL("http://www.google.com/upload");
7938 request.upload_data_stream = &upload_data_stream;
7939 request.load_flags = 0;
7940
[email protected]3fe8d2f82013-10-17 08:56:077941 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:037942 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:077943 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]02cad5d2013-10-02 08:14:037944
7945 StaticSocketDataProvider data;
7946 session_deps_.socket_factory->AddSocketDataProvider(&data);
7947
7948 TestCompletionCallback callback;
7949 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7950 EXPECT_EQ(ERR_IO_PENDING, rv);
7951 base::MessageLoop::current()->RunUntilIdle();
7952
7953 // Transaction is pending on request body initialization.
7954 ASSERT_FALSE(fake_reader->callback().is_null());
7955
7956 // Return Init()'s result after the transaction gets destroyed.
7957 trans.reset();
7958 fake_reader->callback().Run(OK); // Should not crash.
7959}
7960
[email protected]aeefc9e82010-02-19 16:18:277961// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:027962TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:277963
7964 HttpRequestInfo request;
7965 request.method = "GET";
7966 request.url = GURL("http://www.google.com/");
7967 request.load_flags = 0;
7968
7969 // First transaction will request a resource and receive a Basic challenge
7970 // with realm="first_realm".
7971 MockWrite data_writes1[] = {
7972 MockWrite("GET / HTTP/1.1\r\n"
7973 "Host: www.google.com\r\n"
7974 "Connection: keep-alive\r\n"
7975 "\r\n"),
7976 };
7977 MockRead data_reads1[] = {
7978 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7979 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7980 "\r\n"),
7981 };
7982
7983 // After calling trans->RestartWithAuth(), provide an Authentication header
7984 // for first_realm. The server will reject and provide a challenge with
7985 // second_realm.
7986 MockWrite data_writes2[] = {
7987 MockWrite("GET / HTTP/1.1\r\n"
7988 "Host: www.google.com\r\n"
7989 "Connection: keep-alive\r\n"
7990 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7991 "\r\n"),
7992 };
7993 MockRead data_reads2[] = {
7994 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7995 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7996 "\r\n"),
7997 };
7998
7999 // This again fails, and goes back to first_realm. Make sure that the
8000 // entry is removed from cache.
8001 MockWrite data_writes3[] = {
8002 MockWrite("GET / HTTP/1.1\r\n"
8003 "Host: www.google.com\r\n"
8004 "Connection: keep-alive\r\n"
8005 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8006 "\r\n"),
8007 };
8008 MockRead data_reads3[] = {
8009 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8010 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8011 "\r\n"),
8012 };
8013
8014 // Try one last time (with the correct password) and get the resource.
8015 MockWrite data_writes4[] = {
8016 MockWrite("GET / HTTP/1.1\r\n"
8017 "Host: www.google.com\r\n"
8018 "Connection: keep-alive\r\n"
8019 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8020 "\r\n"),
8021 };
8022 MockRead data_reads4[] = {
8023 MockRead("HTTP/1.1 200 OK\r\n"
8024 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508025 "Content-Length: 5\r\n"
8026 "\r\n"
8027 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278028 };
8029
8030 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8031 data_writes1, arraysize(data_writes1));
8032 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8033 data_writes2, arraysize(data_writes2));
8034 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8035 data_writes3, arraysize(data_writes3));
8036 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8037 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078038 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8039 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8040 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8041 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278042
[email protected]49639fa2011-12-20 23:22:418043 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278044
[email protected]3fe8d2f82013-10-17 08:56:078045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508046 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:078047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]0b0bf032010-09-21 18:08:508048
[email protected]aeefc9e82010-02-19 16:18:278049 // Issue the first request with Authorize headers. There should be a
8050 // password prompt for first_realm waiting to be filled in after the
8051 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418052 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278053 EXPECT_EQ(ERR_IO_PENDING, rv);
8054 rv = callback1.WaitForResult();
8055 EXPECT_EQ(OK, rv);
8056 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508057 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048058 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8059 ASSERT_FALSE(challenge == NULL);
8060 EXPECT_FALSE(challenge->is_proxy);
8061 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8062 EXPECT_EQ("first_realm", challenge->realm);
8063 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278064
8065 // Issue the second request with an incorrect password. There should be a
8066 // password prompt for second_realm waiting to be filled in after the
8067 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418068 TestCompletionCallback callback2;
8069 rv = trans->RestartWithAuth(
8070 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278071 EXPECT_EQ(ERR_IO_PENDING, rv);
8072 rv = callback2.WaitForResult();
8073 EXPECT_EQ(OK, rv);
8074 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508075 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048076 challenge = response->auth_challenge.get();
8077 ASSERT_FALSE(challenge == NULL);
8078 EXPECT_FALSE(challenge->is_proxy);
8079 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8080 EXPECT_EQ("second_realm", challenge->realm);
8081 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278082
8083 // Issue the third request with another incorrect password. There should be
8084 // a password prompt for first_realm waiting to be filled in. If the password
8085 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8086 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418087 TestCompletionCallback callback3;
8088 rv = trans->RestartWithAuth(
8089 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278090 EXPECT_EQ(ERR_IO_PENDING, rv);
8091 rv = callback3.WaitForResult();
8092 EXPECT_EQ(OK, rv);
8093 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508094 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048095 challenge = response->auth_challenge.get();
8096 ASSERT_FALSE(challenge == NULL);
8097 EXPECT_FALSE(challenge->is_proxy);
8098 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8099 EXPECT_EQ("first_realm", challenge->realm);
8100 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278101
8102 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418103 TestCompletionCallback callback4;
8104 rv = trans->RestartWithAuth(
8105 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278106 EXPECT_EQ(ERR_IO_PENDING, rv);
8107 rv = callback4.WaitForResult();
8108 EXPECT_EQ(OK, rv);
8109 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508110 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278111 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8112}
8113
[email protected]23e482282013-06-14 16:08:028114TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:038115 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:238116 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:428117
[email protected]8a0fc822013-06-27 20:52:438118 std::string alternate_protocol_http_header =
8119 GetAlternateProtocolHttpHeader();
8120
[email protected]564b4912010-03-09 16:30:428121 MockRead data_reads[] = {
8122 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438123 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428124 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068125 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428126 };
8127
8128 HttpRequestInfo request;
8129 request.method = "GET";
8130 request.url = GURL("http://www.google.com/");
8131 request.load_flags = 0;
8132
8133 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8134
[email protected]bb88e1d32013-05-03 23:11:078135 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428136
[email protected]49639fa2011-12-20 23:22:418137 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428138
[email protected]bb88e1d32013-05-03 23:11:078139 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[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]564b4912010-03-09 16:30:428142
[email protected]49639fa2011-12-20 23:22:418143 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428144 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538145
[email protected]2fbaecf22010-07-22 22:20:358146 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558147 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538148 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428149 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538150 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428151
8152 EXPECT_EQ(OK, callback.WaitForResult());
8153
8154 const HttpResponseInfo* response = trans->GetResponseInfo();
8155 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508156 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428157 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538158 EXPECT_FALSE(response->was_fetched_via_spdy);
8159 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428160
8161 std::string response_data;
8162 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8163 EXPECT_EQ("hello world", response_data);
8164
[email protected]17291a022011-10-10 07:32:538165 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8166 const PortAlternateProtocolPair alternate =
8167 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8168 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:428169 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:438170 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:428171 EXPECT_TRUE(expected_alternate.Equals(alternate));
8172}
8173
[email protected]23e482282013-06-14 16:08:028174TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238175 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:388176 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:428177
8178 HttpRequestInfo request;
8179 request.method = "GET";
8180 request.url = GURL("http://www.google.com/");
8181 request.load_flags = 0;
8182
[email protected]d973e99a2012-02-17 21:02:368183 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428184 StaticSocketDataProvider first_data;
8185 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078186 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428187
8188 MockRead data_reads[] = {
8189 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8190 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068191 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428192 };
8193 StaticSocketDataProvider second_data(
8194 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078195 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428196
[email protected]bb88e1d32013-05-03 23:11:078197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428198
[email protected]30d4c022013-07-18 22:58:168199 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538200 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118201 // Port must be < 1024, or the header will be ignored (since initial port was
8202 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538203 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118204 HostPortPair::FromURL(request.url),
8205 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438206 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428207
[email protected]262eec82013-03-19 21:01:368208 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418210 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428211
[email protected]49639fa2011-12-20 23:22:418212 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428213 EXPECT_EQ(ERR_IO_PENDING, rv);
8214 EXPECT_EQ(OK, callback.WaitForResult());
8215
8216 const HttpResponseInfo* response = trans->GetResponseInfo();
8217 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508218 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428219 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8220
8221 std::string response_data;
8222 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8223 EXPECT_EQ("hello world", response_data);
8224
[email protected]17291a022011-10-10 07:32:538225 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118226 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538227 const PortAlternateProtocolPair alternate =
8228 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118229 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538230 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428231}
8232
[email protected]23e482282013-06-14 16:08:028233TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238234 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118235 // Ensure that we're not allowed to redirect traffic via an alternate
8236 // protocol to an unrestricted (port >= 1024) when the original traffic was
8237 // on a restricted port (port < 1024). Ensure that we can redirect in all
8238 // other cases.
8239 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118240
8241 HttpRequestInfo restricted_port_request;
8242 restricted_port_request.method = "GET";
8243 restricted_port_request.url = GURL("http://www.google.com:1023/");
8244 restricted_port_request.load_flags = 0;
8245
[email protected]d973e99a2012-02-17 21:02:368246 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118247 StaticSocketDataProvider first_data;
8248 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078249 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118250
8251 MockRead data_reads[] = {
8252 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8253 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068254 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118255 };
8256 StaticSocketDataProvider second_data(
8257 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078258 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118259
[email protected]bb88e1d32013-05-03 23:11:078260 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118261
[email protected]30d4c022013-07-18 22:58:168262 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538263 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118264 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538265 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118266 HostPortPair::FromURL(restricted_port_request.url),
8267 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438268 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118269
[email protected]262eec82013-03-19 21:01:368270 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418272 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118273
[email protected]49639fa2011-12-20 23:22:418274 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368275 &restricted_port_request,
8276 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118277 EXPECT_EQ(ERR_IO_PENDING, rv);
8278 // Invalid change to unrestricted port should fail.
8279 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198280}
[email protected]3912662a32011-10-04 00:51:118281
[email protected]23e482282013-06-14 16:08:028282TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198283 AlternateProtocolPortRestrictedPermitted) {
8284 // Ensure that we're allowed to redirect traffic via an alternate
8285 // protocol to an unrestricted (port >= 1024) when the original traffic was
8286 // on a restricted port (port < 1024) if we set
8287 // enable_user_alternate_protocol_ports.
8288
8289 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078290 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198291
8292 HttpRequestInfo restricted_port_request;
8293 restricted_port_request.method = "GET";
8294 restricted_port_request.url = GURL("http://www.google.com:1023/");
8295 restricted_port_request.load_flags = 0;
8296
8297 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8298 StaticSocketDataProvider first_data;
8299 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078300 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198301
8302 MockRead data_reads[] = {
8303 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8304 MockRead("hello world"),
8305 MockRead(ASYNC, OK),
8306 };
8307 StaticSocketDataProvider second_data(
8308 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078309 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198310
[email protected]bb88e1d32013-05-03 23:11:078311 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198312
[email protected]30d4c022013-07-18 22:58:168313 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198314 session->http_server_properties();
8315 const int kUnrestrictedAlternatePort = 1024;
8316 http_server_properties->SetAlternateProtocol(
8317 HostPortPair::FromURL(restricted_port_request.url),
8318 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438319 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198320
[email protected]262eec82013-03-19 21:01:368321 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198323 TestCompletionCallback callback;
8324
8325 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368326 &restricted_port_request,
8327 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198328 // Change to unrestricted port should succeed.
8329 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118330}
8331
[email protected]23e482282013-06-14 16:08:028332TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238333 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118334 // Ensure that we're not allowed to redirect traffic via an alternate
8335 // protocol to an unrestricted (port >= 1024) when the original traffic was
8336 // on a restricted port (port < 1024). Ensure that we can redirect in all
8337 // other cases.
8338 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118339
8340 HttpRequestInfo restricted_port_request;
8341 restricted_port_request.method = "GET";
8342 restricted_port_request.url = GURL("http://www.google.com:1023/");
8343 restricted_port_request.load_flags = 0;
8344
[email protected]d973e99a2012-02-17 21:02:368345 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118346 StaticSocketDataProvider first_data;
8347 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078348 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118349
8350 MockRead data_reads[] = {
8351 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8352 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068353 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118354 };
8355 StaticSocketDataProvider second_data(
8356 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078357 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118358
[email protected]bb88e1d32013-05-03 23:11:078359 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118360
[email protected]30d4c022013-07-18 22:58:168361 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538362 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118363 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538364 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118365 HostPortPair::FromURL(restricted_port_request.url),
8366 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438367 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118368
[email protected]262eec82013-03-19 21:01:368369 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418371 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118372
[email protected]49639fa2011-12-20 23:22:418373 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368374 &restricted_port_request,
8375 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118376 EXPECT_EQ(ERR_IO_PENDING, rv);
8377 // Valid change to restricted port should pass.
8378 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118379}
8380
[email protected]23e482282013-06-14 16:08:028381TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238382 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118383 // Ensure that we're not allowed to redirect traffic via an alternate
8384 // protocol to an unrestricted (port >= 1024) when the original traffic was
8385 // on a restricted port (port < 1024). Ensure that we can redirect in all
8386 // other cases.
8387 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118388
8389 HttpRequestInfo unrestricted_port_request;
8390 unrestricted_port_request.method = "GET";
8391 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8392 unrestricted_port_request.load_flags = 0;
8393
[email protected]d973e99a2012-02-17 21:02:368394 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118395 StaticSocketDataProvider first_data;
8396 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078397 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118398
8399 MockRead data_reads[] = {
8400 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8401 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068402 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118403 };
8404 StaticSocketDataProvider second_data(
8405 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078406 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118407
[email protected]bb88e1d32013-05-03 23:11:078408 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118409
[email protected]30d4c022013-07-18 22:58:168410 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538411 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118412 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538413 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118414 HostPortPair::FromURL(unrestricted_port_request.url),
8415 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438416 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118417
[email protected]262eec82013-03-19 21:01:368418 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418420 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118421
[email protected]49639fa2011-12-20 23:22:418422 int rv = trans->Start(
8423 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118424 EXPECT_EQ(ERR_IO_PENDING, rv);
8425 // Valid change to restricted port should pass.
8426 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118427}
8428
[email protected]23e482282013-06-14 16:08:028429TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238430 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118431 // Ensure that we're not allowed to redirect traffic via an alternate
8432 // protocol to an unrestricted (port >= 1024) when the original traffic was
8433 // on a restricted port (port < 1024). Ensure that we can redirect in all
8434 // other cases.
8435 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118436
8437 HttpRequestInfo unrestricted_port_request;
8438 unrestricted_port_request.method = "GET";
8439 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8440 unrestricted_port_request.load_flags = 0;
8441
[email protected]d973e99a2012-02-17 21:02:368442 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118443 StaticSocketDataProvider first_data;
8444 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078445 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118446
8447 MockRead data_reads[] = {
8448 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8449 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068450 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118451 };
8452 StaticSocketDataProvider second_data(
8453 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078454 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118455
[email protected]bb88e1d32013-05-03 23:11:078456 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118457
[email protected]30d4c022013-07-18 22:58:168458 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538459 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118460 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538461 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118462 HostPortPair::FromURL(unrestricted_port_request.url),
8463 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438464 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118465
[email protected]262eec82013-03-19 21:01:368466 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508467 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418468 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118469
[email protected]49639fa2011-12-20 23:22:418470 int rv = trans->Start(
8471 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118472 EXPECT_EQ(ERR_IO_PENDING, rv);
8473 // Valid change to an unrestricted port should pass.
8474 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118475}
8476
[email protected]23e482282013-06-14 16:08:028477TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238478 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028479 // Ensure that we're not allowed to redirect traffic via an alternate
8480 // protocol to an unsafe port, and that we resume the second
8481 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8482 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028483
8484 HttpRequestInfo request;
8485 request.method = "GET";
8486 request.url = GURL("http://www.google.com/");
8487 request.load_flags = 0;
8488
8489 // The alternate protocol request will error out before we attempt to connect,
8490 // so only the standard HTTP request will try to connect.
8491 MockRead data_reads[] = {
8492 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8493 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068494 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028495 };
8496 StaticSocketDataProvider data(
8497 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078498 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028499
[email protected]bb88e1d32013-05-03 23:11:078500 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028501
[email protected]30d4c022013-07-18 22:58:168502 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028503 session->http_server_properties();
8504 const int kUnsafePort = 7;
8505 http_server_properties->SetAlternateProtocol(
8506 HostPortPair::FromURL(request.url),
8507 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438508 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028509
[email protected]262eec82013-03-19 21:01:368510 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508511 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028512 TestCompletionCallback callback;
8513
8514 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8515 EXPECT_EQ(ERR_IO_PENDING, rv);
8516 // The HTTP request should succeed.
8517 EXPECT_EQ(OK, callback.WaitForResult());
8518
8519 // Disable alternate protocol before the asserts.
8520 HttpStreamFactory::set_use_alternate_protocols(false);
8521
8522 const HttpResponseInfo* response = trans->GetResponseInfo();
8523 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508524 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028525 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8526
8527 std::string response_data;
8528 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8529 EXPECT_EQ("hello world", response_data);
8530}
8531
[email protected]23e482282013-06-14 16:08:028532TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388533 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038534 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548535
8536 HttpRequestInfo request;
8537 request.method = "GET";
8538 request.url = GURL("http://www.google.com/");
8539 request.load_flags = 0;
8540
[email protected]8a0fc822013-06-27 20:52:438541 std::string alternate_protocol_http_header =
8542 GetAlternateProtocolHttpHeader();
8543
[email protected]2ff8b312010-04-26 22:20:548544 MockRead data_reads[] = {
8545 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438546 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548547 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178548 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8549 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548550 };
8551
8552 StaticSocketDataProvider first_transaction(
8553 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078554 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548555
[email protected]8ddf8322012-02-23 18:08:068556 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028557 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078558 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548559
[email protected]cdf8f7e72013-05-23 10:56:468560 scoped_ptr<SpdyFrame> req(
8561 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138562 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548563
[email protected]23e482282013-06-14 16:08:028564 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8565 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548566 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138567 CreateMockRead(*resp),
8568 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068569 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548570 };
8571
[email protected]dd54bd82012-07-19 23:44:578572 DelayedSocketData spdy_data(
8573 1, // wait for one write to finish before reading.
8574 spdy_reads, arraysize(spdy_reads),
8575 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078576 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548577
[email protected]d973e99a2012-02-17 21:02:368578 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558579 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8580 NULL, 0, NULL, 0);
8581 hanging_non_alternate_protocol_socket.set_connect_data(
8582 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078583 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558584 &hanging_non_alternate_protocol_socket);
8585
[email protected]49639fa2011-12-20 23:22:418586 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548587
[email protected]bb88e1d32013-05-03 23:11:078588 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368589 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508590 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548591
[email protected]49639fa2011-12-20 23:22:418592 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548593 EXPECT_EQ(ERR_IO_PENDING, rv);
8594 EXPECT_EQ(OK, callback.WaitForResult());
8595
8596 const HttpResponseInfo* response = trans->GetResponseInfo();
8597 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508598 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548599 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8600
8601 std::string response_data;
8602 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8603 EXPECT_EQ("hello world", response_data);
8604
[email protected]90499482013-06-01 00:39:508605 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548606
[email protected]49639fa2011-12-20 23:22:418607 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548608 EXPECT_EQ(ERR_IO_PENDING, rv);
8609 EXPECT_EQ(OK, callback.WaitForResult());
8610
8611 response = trans->GetResponseInfo();
8612 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508613 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548614 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538615 EXPECT_TRUE(response->was_fetched_via_spdy);
8616 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548617
8618 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8619 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548620}
8621
[email protected]23e482282013-06-14 16:08:028622TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558623 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038624 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558625
8626 HttpRequestInfo request;
8627 request.method = "GET";
8628 request.url = GURL("http://www.google.com/");
8629 request.load_flags = 0;
8630
[email protected]8a0fc822013-06-27 20:52:438631 std::string alternate_protocol_http_header =
8632 GetAlternateProtocolHttpHeader();
8633
[email protected]2d6728692011-03-12 01:39:558634 MockRead data_reads[] = {
8635 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438636 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558637 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178638 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068639 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558640 };
8641
8642 StaticSocketDataProvider first_transaction(
8643 data_reads, arraysize(data_reads), NULL, 0);
8644 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078645 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558646
[email protected]d973e99a2012-02-17 21:02:368647 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558648 StaticSocketDataProvider hanging_socket(
8649 NULL, 0, NULL, 0);
8650 hanging_socket.set_connect_data(never_finishing_connect);
8651 // Socket 2 and 3 are the hanging Alternate-Protocol and
8652 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078653 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8654 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558655
[email protected]8ddf8322012-02-23 18:08:068656 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028657 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558659
[email protected]cdf8f7e72013-05-23 10:56:468660 scoped_ptr<SpdyFrame> req1(
8661 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8662 scoped_ptr<SpdyFrame> req2(
8663 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558664 MockWrite spdy_writes[] = {
8665 CreateMockWrite(*req1),
8666 CreateMockWrite(*req2),
8667 };
[email protected]23e482282013-06-14 16:08:028668 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8669 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8670 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8671 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558672 MockRead spdy_reads[] = {
8673 CreateMockRead(*resp1),
8674 CreateMockRead(*data1),
8675 CreateMockRead(*resp2),
8676 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068677 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558678 };
8679
[email protected]dd54bd82012-07-19 23:44:578680 DelayedSocketData spdy_data(
8681 2, // wait for writes to finish before reading.
8682 spdy_reads, arraysize(spdy_reads),
8683 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558684 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078685 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558686
8687 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078688 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558689
[email protected]bb88e1d32013-05-03 23:11:078690 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418691 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508692 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558693
[email protected]49639fa2011-12-20 23:22:418694 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558695 EXPECT_EQ(ERR_IO_PENDING, rv);
8696 EXPECT_EQ(OK, callback1.WaitForResult());
8697
8698 const HttpResponseInfo* response = trans1.GetResponseInfo();
8699 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508700 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558701 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8702
8703 std::string response_data;
8704 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8705 EXPECT_EQ("hello world", response_data);
8706
[email protected]49639fa2011-12-20 23:22:418707 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508708 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418709 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558710 EXPECT_EQ(ERR_IO_PENDING, rv);
8711
[email protected]49639fa2011-12-20 23:22:418712 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508713 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418714 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558715 EXPECT_EQ(ERR_IO_PENDING, rv);
8716
8717 EXPECT_EQ(OK, callback2.WaitForResult());
8718 EXPECT_EQ(OK, callback3.WaitForResult());
8719
8720 response = trans2.GetResponseInfo();
8721 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508722 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558723 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8724 EXPECT_TRUE(response->was_fetched_via_spdy);
8725 EXPECT_TRUE(response->was_npn_negotiated);
8726 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8727 EXPECT_EQ("hello!", response_data);
8728
8729 response = trans3.GetResponseInfo();
8730 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508731 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558732 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8733 EXPECT_TRUE(response->was_fetched_via_spdy);
8734 EXPECT_TRUE(response->was_npn_negotiated);
8735 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8736 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558737}
8738
[email protected]23e482282013-06-14 16:08:028739TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558740 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038741 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558742
8743 HttpRequestInfo request;
8744 request.method = "GET";
8745 request.url = GURL("http://www.google.com/");
8746 request.load_flags = 0;
8747
[email protected]8a0fc822013-06-27 20:52:438748 std::string alternate_protocol_http_header =
8749 GetAlternateProtocolHttpHeader();
8750
[email protected]2d6728692011-03-12 01:39:558751 MockRead data_reads[] = {
8752 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438753 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558754 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178755 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068756 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558757 };
8758
8759 StaticSocketDataProvider first_transaction(
8760 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078761 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558762
[email protected]8ddf8322012-02-23 18:08:068763 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028764 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078765 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558766
[email protected]d973e99a2012-02-17 21:02:368767 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558768 StaticSocketDataProvider hanging_alternate_protocol_socket(
8769 NULL, 0, NULL, 0);
8770 hanging_alternate_protocol_socket.set_connect_data(
8771 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078772 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558773 &hanging_alternate_protocol_socket);
8774
8775 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078776 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558777
[email protected]49639fa2011-12-20 23:22:418778 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558779
[email protected]bb88e1d32013-05-03 23:11:078780 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368781 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508782 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558783
[email protected]49639fa2011-12-20 23:22:418784 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558785 EXPECT_EQ(ERR_IO_PENDING, rv);
8786 EXPECT_EQ(OK, callback.WaitForResult());
8787
8788 const HttpResponseInfo* response = trans->GetResponseInfo();
8789 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508790 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558791 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8792
8793 std::string response_data;
8794 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8795 EXPECT_EQ("hello world", response_data);
8796
[email protected]90499482013-06-01 00:39:508797 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558798
[email protected]49639fa2011-12-20 23:22:418799 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558800 EXPECT_EQ(ERR_IO_PENDING, rv);
8801 EXPECT_EQ(OK, callback.WaitForResult());
8802
8803 response = trans->GetResponseInfo();
8804 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508805 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558806 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8807 EXPECT_FALSE(response->was_fetched_via_spdy);
8808 EXPECT_FALSE(response->was_npn_negotiated);
8809
8810 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8811 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558812}
8813
[email protected]631f1322010-04-30 17:59:118814class CapturingProxyResolver : public ProxyResolver {
8815 public:
8816 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8817 virtual ~CapturingProxyResolver() {}
8818
8819 virtual int GetProxyForURL(const GURL& url,
8820 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318821 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118822 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168823 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408824 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8825 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428826 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118827 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428828 return OK;
[email protected]631f1322010-04-30 17:59:118829 }
8830
[email protected]46fadfd2013-02-06 09:40:168831 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118832 NOTREACHED();
8833 }
8834
[email protected]f2c971f2011-11-08 00:33:178835 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8836 NOTREACHED();
8837 return LOAD_STATE_IDLE;
8838 }
8839
[email protected]46fadfd2013-02-06 09:40:168840 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408841 NOTREACHED();
8842 }
8843
[email protected]24476402010-07-20 20:55:178844 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168845 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428846 return OK;
[email protected]631f1322010-04-30 17:59:118847 }
8848
[email protected]24476402010-07-20 20:55:178849 const std::vector<GURL>& resolved() const { return resolved_; }
8850
8851 private:
[email protected]631f1322010-04-30 17:59:118852 std::vector<GURL> resolved_;
8853
8854 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8855};
8856
[email protected]23e482282013-06-14 16:08:028857TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238858 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388859 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038860 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118861
8862 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428863 proxy_config.set_auto_detect(true);
8864 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118865
[email protected]631f1322010-04-30 17:59:118866 CapturingProxyResolver* capturing_proxy_resolver =
8867 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078868 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388869 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8870 NULL));
[email protected]029c83b62013-01-24 05:28:208871 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078872 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118873
8874 HttpRequestInfo request;
8875 request.method = "GET";
8876 request.url = GURL("http://www.google.com/");
8877 request.load_flags = 0;
8878
[email protected]8a0fc822013-06-27 20:52:438879 std::string alternate_protocol_http_header =
8880 GetAlternateProtocolHttpHeader();
8881
[email protected]631f1322010-04-30 17:59:118882 MockRead data_reads[] = {
8883 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438884 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118885 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178886 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068887 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118888 };
8889
8890 StaticSocketDataProvider first_transaction(
8891 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078892 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:118893
[email protected]8ddf8322012-02-23 18:08:068894 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028895 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078896 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:118897
[email protected]cdf8f7e72013-05-23 10:56:468898 scoped_ptr<SpdyFrame> req(
8899 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:118900 MockWrite spdy_writes[] = {
8901 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8902 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:428903 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:468904 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:118905 };
8906
[email protected]d911f1b2010-05-05 22:39:428907 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8908
[email protected]23e482282013-06-14 16:08:028909 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8910 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:118911 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068912 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:138913 CreateMockRead(*resp.get(), 4), // 2, 4
8914 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:068915 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:118916 };
8917
[email protected]dd54bd82012-07-19 23:44:578918 OrderedSocketData spdy_data(
8919 spdy_reads, arraysize(spdy_reads),
8920 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078921 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:118922
[email protected]d973e99a2012-02-17 21:02:368923 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558924 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8925 NULL, 0, NULL, 0);
8926 hanging_non_alternate_protocol_socket.set_connect_data(
8927 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078928 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558929 &hanging_non_alternate_protocol_socket);
8930
[email protected]49639fa2011-12-20 23:22:418931 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:118932
[email protected]bb88e1d32013-05-03 23:11:078933 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368934 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508935 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118936
[email protected]49639fa2011-12-20 23:22:418937 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118938 EXPECT_EQ(ERR_IO_PENDING, rv);
8939 EXPECT_EQ(OK, callback.WaitForResult());
8940
8941 const HttpResponseInfo* response = trans->GetResponseInfo();
8942 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508943 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118944 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538945 EXPECT_FALSE(response->was_fetched_via_spdy);
8946 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118947
8948 std::string response_data;
8949 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8950 EXPECT_EQ("hello world", response_data);
8951
[email protected]90499482013-06-01 00:39:508952 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118953
[email protected]49639fa2011-12-20 23:22:418954 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118955 EXPECT_EQ(ERR_IO_PENDING, rv);
8956 EXPECT_EQ(OK, callback.WaitForResult());
8957
8958 response = trans->GetResponseInfo();
8959 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508960 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118961 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538962 EXPECT_TRUE(response->was_fetched_via_spdy);
8963 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118964
8965 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8966 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558967 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:428968 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:118969 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:428970 EXPECT_EQ("https://www.google.com/",
8971 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:118972
[email protected]029c83b62013-01-24 05:28:208973 LoadTimingInfo load_timing_info;
8974 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8975 TestLoadTimingNotReusedWithPac(load_timing_info,
8976 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:118977}
[email protected]631f1322010-04-30 17:59:118978
[email protected]23e482282013-06-14 16:08:028979TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:548980 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:388981 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038982 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548983
8984 HttpRequestInfo request;
8985 request.method = "GET";
8986 request.url = GURL("http://www.google.com/");
8987 request.load_flags = 0;
8988
[email protected]8a0fc822013-06-27 20:52:438989 std::string alternate_protocol_http_header =
8990 GetAlternateProtocolHttpHeader();
8991
[email protected]2ff8b312010-04-26 22:20:548992 MockRead data_reads[] = {
8993 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438994 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548995 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068996 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:548997 };
8998
8999 StaticSocketDataProvider first_transaction(
9000 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079001 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549002
[email protected]8ddf8322012-02-23 18:08:069003 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029004 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549006
[email protected]cdf8f7e72013-05-23 10:56:469007 scoped_ptr<SpdyFrame> req(
9008 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139009 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549010
[email protected]23e482282013-06-14 16:08:029011 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9012 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549013 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139014 CreateMockRead(*resp),
9015 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069016 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549017 };
9018
[email protected]dd54bd82012-07-19 23:44:579019 DelayedSocketData spdy_data(
9020 1, // wait for one write to finish before reading.
9021 spdy_reads, arraysize(spdy_reads),
9022 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079023 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549024
[email protected]83039bb2011-12-09 18:43:559025 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549026
[email protected]bb88e1d32013-05-03 23:11:079027 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549028
[email protected]262eec82013-03-19 21:01:369029 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549031
[email protected]49639fa2011-12-20 23:22:419032 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419034 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549035
9036 const HttpResponseInfo* response = trans->GetResponseInfo();
9037 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509038 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549039 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9040
9041 std::string response_data;
9042 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9043 EXPECT_EQ("hello world", response_data);
9044
9045 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389046 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409047 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9048 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:279049 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269050 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389051
[email protected]90499482013-06-01 00:39:509052 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549053
[email protected]49639fa2011-12-20 23:22:419054 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549055 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419056 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549057
9058 response = trans->GetResponseInfo();
9059 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509060 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549061 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539062 EXPECT_TRUE(response->was_fetched_via_spdy);
9063 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549064
9065 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9066 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429067}
9068
[email protected]044de0642010-06-17 10:42:159069// GenerateAuthToken is a mighty big test.
9070// It tests all permutation of GenerateAuthToken behavior:
9071// - Synchronous and Asynchronous completion.
9072// - OK or error on completion.
9073// - Direct connection, non-authenticating proxy, and authenticating proxy.
9074// - HTTP or HTTPS backend (to include proxy tunneling).
9075// - Non-authenticating and authenticating backend.
9076//
[email protected]fe3b7dc2012-02-03 19:52:099077// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159078// problems generating an auth token for an authenticating proxy, we don't
9079// need to test all permutations of the backend server).
9080//
9081// The test proceeds by going over each of the configuration cases, and
9082// potentially running up to three rounds in each of the tests. The TestConfig
9083// specifies both the configuration for the test as well as the expectations
9084// for the results.
[email protected]23e482282013-06-14 16:08:029085TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509086 static const char kServer[] = "http://www.example.com";
9087 static const char kSecureServer[] = "https://www.example.com";
9088 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159089 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9090
9091 enum AuthTiming {
9092 AUTH_NONE,
9093 AUTH_SYNC,
9094 AUTH_ASYNC,
9095 };
9096
9097 const MockWrite kGet(
9098 "GET / HTTP/1.1\r\n"
9099 "Host: www.example.com\r\n"
9100 "Connection: keep-alive\r\n\r\n");
9101 const MockWrite kGetProxy(
9102 "GET http://www.example.com/ HTTP/1.1\r\n"
9103 "Host: www.example.com\r\n"
9104 "Proxy-Connection: keep-alive\r\n\r\n");
9105 const MockWrite kGetAuth(
9106 "GET / HTTP/1.1\r\n"
9107 "Host: www.example.com\r\n"
9108 "Connection: keep-alive\r\n"
9109 "Authorization: auth_token\r\n\r\n");
9110 const MockWrite kGetProxyAuth(
9111 "GET http://www.example.com/ HTTP/1.1\r\n"
9112 "Host: www.example.com\r\n"
9113 "Proxy-Connection: keep-alive\r\n"
9114 "Proxy-Authorization: auth_token\r\n\r\n");
9115 const MockWrite kGetAuthThroughProxy(
9116 "GET http://www.example.com/ HTTP/1.1\r\n"
9117 "Host: www.example.com\r\n"
9118 "Proxy-Connection: keep-alive\r\n"
9119 "Authorization: auth_token\r\n\r\n");
9120 const MockWrite kGetAuthWithProxyAuth(
9121 "GET http://www.example.com/ HTTP/1.1\r\n"
9122 "Host: www.example.com\r\n"
9123 "Proxy-Connection: keep-alive\r\n"
9124 "Proxy-Authorization: auth_token\r\n"
9125 "Authorization: auth_token\r\n\r\n");
9126 const MockWrite kConnect(
9127 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9128 "Host: www.example.com\r\n"
9129 "Proxy-Connection: keep-alive\r\n\r\n");
9130 const MockWrite kConnectProxyAuth(
9131 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9132 "Host: www.example.com\r\n"
9133 "Proxy-Connection: keep-alive\r\n"
9134 "Proxy-Authorization: auth_token\r\n\r\n");
9135
9136 const MockRead kSuccess(
9137 "HTTP/1.1 200 OK\r\n"
9138 "Content-Type: text/html; charset=iso-8859-1\r\n"
9139 "Content-Length: 3\r\n\r\n"
9140 "Yes");
9141 const MockRead kFailure(
9142 "Should not be called.");
9143 const MockRead kServerChallenge(
9144 "HTTP/1.1 401 Unauthorized\r\n"
9145 "WWW-Authenticate: Mock realm=server\r\n"
9146 "Content-Type: text/html; charset=iso-8859-1\r\n"
9147 "Content-Length: 14\r\n\r\n"
9148 "Unauthorized\r\n");
9149 const MockRead kProxyChallenge(
9150 "HTTP/1.1 407 Unauthorized\r\n"
9151 "Proxy-Authenticate: Mock realm=proxy\r\n"
9152 "Proxy-Connection: close\r\n"
9153 "Content-Type: text/html; charset=iso-8859-1\r\n"
9154 "Content-Length: 14\r\n\r\n"
9155 "Unauthorized\r\n");
9156 const MockRead kProxyConnected(
9157 "HTTP/1.1 200 Connection Established\r\n\r\n");
9158
9159 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9160 // no constructors, but the C++ compiler on Windows warns about
9161 // unspecified data in compound literals. So, moved to using constructors,
9162 // and TestRound's created with the default constructor should not be used.
9163 struct TestRound {
9164 TestRound()
9165 : expected_rv(ERR_UNEXPECTED),
9166 extra_write(NULL),
9167 extra_read(NULL) {
9168 }
9169 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9170 int expected_rv_arg)
9171 : write(write_arg),
9172 read(read_arg),
9173 expected_rv(expected_rv_arg),
9174 extra_write(NULL),
9175 extra_read(NULL) {
9176 }
9177 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9178 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019179 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159180 : write(write_arg),
9181 read(read_arg),
9182 expected_rv(expected_rv_arg),
9183 extra_write(extra_write_arg),
9184 extra_read(extra_read_arg) {
9185 }
9186 MockWrite write;
9187 MockRead read;
9188 int expected_rv;
9189 const MockWrite* extra_write;
9190 const MockRead* extra_read;
9191 };
9192
9193 static const int kNoSSL = 500;
9194
9195 struct TestConfig {
9196 const char* proxy_url;
9197 AuthTiming proxy_auth_timing;
9198 int proxy_auth_rv;
9199 const char* server_url;
9200 AuthTiming server_auth_timing;
9201 int server_auth_rv;
9202 int num_auth_rounds;
9203 int first_ssl_round;
9204 TestRound rounds[3];
9205 } test_configs[] = {
9206 // Non-authenticating HTTP server with a direct connection.
9207 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9208 { TestRound(kGet, kSuccess, OK)}},
9209 // Authenticating HTTP server with a direct connection.
9210 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9211 { TestRound(kGet, kServerChallenge, OK),
9212 TestRound(kGetAuth, kSuccess, OK)}},
9213 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9214 { TestRound(kGet, kServerChallenge, OK),
9215 TestRound(kGetAuth, kFailure, kAuthErr)}},
9216 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9217 { TestRound(kGet, kServerChallenge, OK),
9218 TestRound(kGetAuth, kSuccess, OK)}},
9219 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9220 { TestRound(kGet, kServerChallenge, OK),
9221 TestRound(kGetAuth, kFailure, kAuthErr)}},
9222 // Non-authenticating HTTP server through a non-authenticating proxy.
9223 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9224 { TestRound(kGetProxy, kSuccess, OK)}},
9225 // Authenticating HTTP server through a non-authenticating proxy.
9226 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9227 { TestRound(kGetProxy, kServerChallenge, OK),
9228 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9229 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9230 { TestRound(kGetProxy, kServerChallenge, OK),
9231 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9232 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9233 { TestRound(kGetProxy, kServerChallenge, OK),
9234 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9235 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9236 { TestRound(kGetProxy, kServerChallenge, OK),
9237 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9238 // Non-authenticating HTTP server through an authenticating proxy.
9239 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9240 { TestRound(kGetProxy, kProxyChallenge, OK),
9241 TestRound(kGetProxyAuth, kSuccess, OK)}},
9242 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9243 { TestRound(kGetProxy, kProxyChallenge, OK),
9244 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9245 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9246 { TestRound(kGetProxy, kProxyChallenge, OK),
9247 TestRound(kGetProxyAuth, kSuccess, OK)}},
9248 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9249 { TestRound(kGetProxy, kProxyChallenge, OK),
9250 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9251 // Authenticating HTTP server through an authenticating proxy.
9252 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9253 { TestRound(kGetProxy, kProxyChallenge, OK),
9254 TestRound(kGetProxyAuth, kServerChallenge, OK),
9255 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9256 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9257 { TestRound(kGetProxy, kProxyChallenge, OK),
9258 TestRound(kGetProxyAuth, kServerChallenge, OK),
9259 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9260 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9261 { TestRound(kGetProxy, kProxyChallenge, OK),
9262 TestRound(kGetProxyAuth, kServerChallenge, OK),
9263 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9264 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9265 { TestRound(kGetProxy, kProxyChallenge, OK),
9266 TestRound(kGetProxyAuth, kServerChallenge, OK),
9267 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9268 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9269 { TestRound(kGetProxy, kProxyChallenge, OK),
9270 TestRound(kGetProxyAuth, kServerChallenge, OK),
9271 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9272 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9273 { TestRound(kGetProxy, kProxyChallenge, OK),
9274 TestRound(kGetProxyAuth, kServerChallenge, OK),
9275 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9276 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9277 { TestRound(kGetProxy, kProxyChallenge, OK),
9278 TestRound(kGetProxyAuth, kServerChallenge, OK),
9279 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9280 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9281 { TestRound(kGetProxy, kProxyChallenge, OK),
9282 TestRound(kGetProxyAuth, kServerChallenge, OK),
9283 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9284 // Non-authenticating HTTPS server with a direct connection.
9285 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9286 { TestRound(kGet, kSuccess, OK)}},
9287 // Authenticating HTTPS server with a direct connection.
9288 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9289 { TestRound(kGet, kServerChallenge, OK),
9290 TestRound(kGetAuth, kSuccess, OK)}},
9291 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9292 { TestRound(kGet, kServerChallenge, OK),
9293 TestRound(kGetAuth, kFailure, kAuthErr)}},
9294 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9295 { TestRound(kGet, kServerChallenge, OK),
9296 TestRound(kGetAuth, kSuccess, OK)}},
9297 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9298 { TestRound(kGet, kServerChallenge, OK),
9299 TestRound(kGetAuth, kFailure, kAuthErr)}},
9300 // Non-authenticating HTTPS server with a non-authenticating proxy.
9301 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9302 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9303 // Authenticating HTTPS server through a non-authenticating proxy.
9304 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9305 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9306 TestRound(kGetAuth, kSuccess, OK)}},
9307 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9308 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9309 TestRound(kGetAuth, kFailure, kAuthErr)}},
9310 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9311 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9312 TestRound(kGetAuth, kSuccess, OK)}},
9313 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9314 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9315 TestRound(kGetAuth, kFailure, kAuthErr)}},
9316 // Non-Authenticating HTTPS server through an authenticating proxy.
9317 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9318 { TestRound(kConnect, kProxyChallenge, OK),
9319 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9320 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9321 { TestRound(kConnect, kProxyChallenge, OK),
9322 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9323 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9324 { TestRound(kConnect, kProxyChallenge, OK),
9325 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9326 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9327 { TestRound(kConnect, kProxyChallenge, OK),
9328 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9329 // Authenticating HTTPS server through an authenticating proxy.
9330 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9331 { TestRound(kConnect, kProxyChallenge, OK),
9332 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9333 &kGet, &kServerChallenge),
9334 TestRound(kGetAuth, kSuccess, OK)}},
9335 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9336 { TestRound(kConnect, kProxyChallenge, OK),
9337 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9338 &kGet, &kServerChallenge),
9339 TestRound(kGetAuth, kFailure, kAuthErr)}},
9340 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9341 { TestRound(kConnect, kProxyChallenge, OK),
9342 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9343 &kGet, &kServerChallenge),
9344 TestRound(kGetAuth, kSuccess, OK)}},
9345 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9346 { TestRound(kConnect, kProxyChallenge, OK),
9347 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9348 &kGet, &kServerChallenge),
9349 TestRound(kGetAuth, kFailure, kAuthErr)}},
9350 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9351 { TestRound(kConnect, kProxyChallenge, OK),
9352 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9353 &kGet, &kServerChallenge),
9354 TestRound(kGetAuth, kSuccess, OK)}},
9355 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9356 { TestRound(kConnect, kProxyChallenge, OK),
9357 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9358 &kGet, &kServerChallenge),
9359 TestRound(kGetAuth, kFailure, kAuthErr)}},
9360 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9361 { TestRound(kConnect, kProxyChallenge, OK),
9362 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9363 &kGet, &kServerChallenge),
9364 TestRound(kGetAuth, kSuccess, OK)}},
9365 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9366 { TestRound(kConnect, kProxyChallenge, OK),
9367 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9368 &kGet, &kServerChallenge),
9369 TestRound(kGetAuth, kFailure, kAuthErr)}},
9370 };
9371
[email protected]044de0642010-06-17 10:42:159372 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089373 HttpAuthHandlerMock::Factory* auth_factory(
9374 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079375 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159376 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269377
9378 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159379 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089380 for (int n = 0; n < 2; n++) {
9381 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9382 std::string auth_challenge = "Mock realm=proxy";
9383 GURL origin(test_config.proxy_url);
9384 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9385 auth_challenge.end());
9386 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9387 origin, BoundNetLog());
9388 auth_handler->SetGenerateExpectation(
9389 test_config.proxy_auth_timing == AUTH_ASYNC,
9390 test_config.proxy_auth_rv);
9391 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9392 }
[email protected]044de0642010-06-17 10:42:159393 }
9394 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009395 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159396 std::string auth_challenge = "Mock realm=server";
9397 GURL origin(test_config.server_url);
9398 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9399 auth_challenge.end());
9400 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9401 origin, BoundNetLog());
9402 auth_handler->SetGenerateExpectation(
9403 test_config.server_auth_timing == AUTH_ASYNC,
9404 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089405 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159406 }
9407 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079408 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129409 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159410 } else {
[email protected]bb88e1d32013-05-03 23:11:079411 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159412 }
9413
9414 HttpRequestInfo request;
9415 request.method = "GET";
9416 request.url = GURL(test_config.server_url);
9417 request.load_flags = 0;
9418
[email protected]bb88e1d32013-05-03 23:11:079419 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079420 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]044de0642010-06-17 10:42:159421
9422 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9423 const TestRound& read_write_round = test_config.rounds[round];
9424
9425 // Set up expected reads and writes.
9426 MockRead reads[2];
9427 reads[0] = read_write_round.read;
9428 size_t length_reads = 1;
9429 if (read_write_round.extra_read) {
9430 reads[1] = *read_write_round.extra_read;
9431 length_reads = 2;
9432 }
9433
9434 MockWrite writes[2];
9435 writes[0] = read_write_round.write;
9436 size_t length_writes = 1;
9437 if (read_write_round.extra_write) {
9438 writes[1] = *read_write_round.extra_write;
9439 length_writes = 2;
9440 }
9441 StaticSocketDataProvider data_provider(
9442 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079443 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159444
9445 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069446 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159447 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079448 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159449 &ssl_socket_data_provider);
9450
9451 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419452 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159453 int rv;
9454 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419455 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159456 } else {
[email protected]49639fa2011-12-20 23:22:419457 rv = trans.RestartWithAuth(
9458 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159459 }
9460 if (rv == ERR_IO_PENDING)
9461 rv = callback.WaitForResult();
9462
9463 // Compare results with expected data.
9464 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509465 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159466 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509467 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159468 } else {
9469 EXPECT_TRUE(response == NULL);
9470 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9471 continue;
9472 }
9473 if (round + 1 < test_config.num_auth_rounds) {
9474 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9475 } else {
9476 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9477 }
9478 }
[email protected]e5ae96a2010-04-14 20:12:459479 }
9480}
9481
[email protected]23e482282013-06-14 16:08:029482TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149483 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149484 HttpAuthHandlerMock::Factory* auth_factory(
9485 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079486 session_deps_.http_auth_handler_factory.reset(auth_factory);
9487 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9488 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9489 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149490
9491 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9492 auth_handler->set_connection_based(true);
9493 std::string auth_challenge = "Mock realm=server";
9494 GURL origin("http://www.example.com");
9495 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9496 auth_challenge.end());
9497 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9498 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089499 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149500
[email protected]c871bce92010-07-15 21:51:149501 int rv = OK;
9502 const HttpResponseInfo* response = NULL;
9503 HttpRequestInfo request;
9504 request.method = "GET";
9505 request.url = origin;
9506 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279507
[email protected]bb88e1d32013-05-03 23:11:079508 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109509
9510 // Use a TCP Socket Pool with only one connection per group. This is used
9511 // to validate that the TCP socket is not released to the pool between
9512 // each round of multi-round authentication.
9513 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289514 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9515 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109516 50, // Max sockets for pool
9517 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289518 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079519 session_deps_.host_resolver.get(),
9520 session_deps_.socket_factory.get(),
9521 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449522 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9523 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029524 mock_pool_manager->SetTransportSocketPool(transport_pool);
[email protected]831e4a32013-11-14 02:14:449525 session_peer.SetClientSocketPoolManager(
9526 mock_pool_manager.PassAs<ClientSocketPoolManager>());
[email protected]7ef4cbbb2011-02-06 11:19:109527
[email protected]262eec82013-03-19 21:01:369528 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509529 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419530 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149531
9532 const MockWrite kGet(
9533 "GET / HTTP/1.1\r\n"
9534 "Host: www.example.com\r\n"
9535 "Connection: keep-alive\r\n\r\n");
9536 const MockWrite kGetAuth(
9537 "GET / HTTP/1.1\r\n"
9538 "Host: www.example.com\r\n"
9539 "Connection: keep-alive\r\n"
9540 "Authorization: auth_token\r\n\r\n");
9541
9542 const MockRead kServerChallenge(
9543 "HTTP/1.1 401 Unauthorized\r\n"
9544 "WWW-Authenticate: Mock realm=server\r\n"
9545 "Content-Type: text/html; charset=iso-8859-1\r\n"
9546 "Content-Length: 14\r\n\r\n"
9547 "Unauthorized\r\n");
9548 const MockRead kSuccess(
9549 "HTTP/1.1 200 OK\r\n"
9550 "Content-Type: text/html; charset=iso-8859-1\r\n"
9551 "Content-Length: 3\r\n\r\n"
9552 "Yes");
9553
9554 MockWrite writes[] = {
9555 // First round
9556 kGet,
9557 // Second round
9558 kGetAuth,
9559 // Third round
9560 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309561 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109562 kGetAuth,
9563 // Competing request
9564 kGet,
[email protected]c871bce92010-07-15 21:51:149565 };
9566 MockRead reads[] = {
9567 // First round
9568 kServerChallenge,
9569 // Second round
9570 kServerChallenge,
9571 // Third round
[email protected]eca50e122010-09-11 14:03:309572 kServerChallenge,
9573 // Fourth round
[email protected]c871bce92010-07-15 21:51:149574 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109575 // Competing response
9576 kSuccess,
[email protected]c871bce92010-07-15 21:51:149577 };
9578 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9579 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079580 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149581
[email protected]7ef4cbbb2011-02-06 11:19:109582 const char* const kSocketGroup = "www.example.com:80";
9583
9584 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149585 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419586 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149587 if (rv == ERR_IO_PENDING)
9588 rv = callback.WaitForResult();
9589 EXPECT_EQ(OK, rv);
9590 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509591 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149592 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289593 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149594
[email protected]7ef4cbbb2011-02-06 11:19:109595 // In between rounds, another request comes in for the same domain.
9596 // It should not be able to grab the TCP socket that trans has already
9597 // claimed.
9598 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509599 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419600 TestCompletionCallback callback_compete;
9601 rv = trans_compete->Start(
9602 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109603 EXPECT_EQ(ERR_IO_PENDING, rv);
9604 // callback_compete.WaitForResult at this point would stall forever,
9605 // since the HttpNetworkTransaction does not release the request back to
9606 // the pool until after authentication completes.
9607
9608 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149609 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419610 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149611 if (rv == ERR_IO_PENDING)
9612 rv = callback.WaitForResult();
9613 EXPECT_EQ(OK, rv);
9614 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509615 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149616 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289617 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149618
[email protected]7ef4cbbb2011-02-06 11:19:109619 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149620 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419621 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149622 if (rv == ERR_IO_PENDING)
9623 rv = callback.WaitForResult();
9624 EXPECT_EQ(OK, rv);
9625 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509626 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149627 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289628 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309629
[email protected]7ef4cbbb2011-02-06 11:19:109630 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309631 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419632 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309633 if (rv == ERR_IO_PENDING)
9634 rv = callback.WaitForResult();
9635 EXPECT_EQ(OK, rv);
9636 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509637 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309638 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289639 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109640
9641 // Read the body since the fourth round was successful. This will also
9642 // release the socket back to the pool.
9643 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509644 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109645 if (rv == ERR_IO_PENDING)
9646 rv = callback.WaitForResult();
9647 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509648 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109649 EXPECT_EQ(0, rv);
9650 // There are still 0 idle sockets, since the trans_compete transaction
9651 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289652 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109653
9654 // The competing request can now finish. Wait for the headers and then
9655 // read the body.
9656 rv = callback_compete.WaitForResult();
9657 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509658 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109659 if (rv == ERR_IO_PENDING)
9660 rv = callback.WaitForResult();
9661 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509662 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109663 EXPECT_EQ(0, rv);
9664
9665 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289666 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149667}
9668
[email protected]65041fa2010-05-21 06:56:539669// This tests the case that a request is issued via http instead of spdy after
9670// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029671TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389672 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169673 std::vector<NextProto> next_protos;
9674 next_protos.push_back(kProtoHTTP11);
9675 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539676 HttpRequestInfo request;
9677 request.method = "GET";
9678 request.url = GURL("https://www.google.com/");
9679 request.load_flags = 0;
9680
9681 MockWrite data_writes[] = {
9682 MockWrite("GET / HTTP/1.1\r\n"
9683 "Host: www.google.com\r\n"
9684 "Connection: keep-alive\r\n\r\n"),
9685 };
9686
[email protected]8a0fc822013-06-27 20:52:439687 std::string alternate_protocol_http_header =
9688 GetAlternateProtocolHttpHeader();
9689
[email protected]65041fa2010-05-21 06:56:539690 MockRead data_reads[] = {
9691 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439692 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539693 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069694 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539695 };
9696
[email protected]8ddf8322012-02-23 18:08:069697 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539698 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9699 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469700 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539701
[email protected]bb88e1d32013-05-03 23:11:079702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539703
9704 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9705 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079706 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539707
[email protected]49639fa2011-12-20 23:22:419708 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539709
[email protected]bb88e1d32013-05-03 23:11:079710 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369711 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509712 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539713
[email protected]49639fa2011-12-20 23:22:419714 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539715
9716 EXPECT_EQ(ERR_IO_PENDING, rv);
9717 EXPECT_EQ(OK, callback.WaitForResult());
9718
9719 const HttpResponseInfo* response = trans->GetResponseInfo();
9720 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509721 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539722 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9723
9724 std::string response_data;
9725 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9726 EXPECT_EQ("hello world", response_data);
9727
9728 EXPECT_FALSE(response->was_fetched_via_spdy);
9729 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539730}
[email protected]26ef6582010-06-24 02:30:479731
[email protected]23e482282013-06-14 16:08:029732TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479733 // Simulate the SSL handshake completing with an NPN negotiation
9734 // followed by an immediate server closing of the socket.
9735 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389736 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039737 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479738
9739 HttpRequestInfo request;
9740 request.method = "GET";
9741 request.url = GURL("https://www.google.com/");
9742 request.load_flags = 0;
9743
[email protected]8ddf8322012-02-23 18:08:069744 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029745 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079746 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479747
[email protected]cdf8f7e72013-05-23 10:56:469748 scoped_ptr<SpdyFrame> req(
9749 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139750 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479751
9752 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069753 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479754 };
9755
[email protected]dd54bd82012-07-19 23:44:579756 DelayedSocketData spdy_data(
9757 0, // don't wait in this case, immediate hangup.
9758 spdy_reads, arraysize(spdy_reads),
9759 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079760 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479761
[email protected]49639fa2011-12-20 23:22:419762 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479763
[email protected]bb88e1d32013-05-03 23:11:079764 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369765 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509766 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479767
[email protected]49639fa2011-12-20 23:22:419768 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479769 EXPECT_EQ(ERR_IO_PENDING, rv);
9770 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479771}
[email protected]65d34382010-07-01 18:12:269772
[email protected]795cbf82013-07-22 09:37:279773// A subclass of HttpAuthHandlerMock that records the request URL when
9774// it gets it. This is needed since the auth handler may get destroyed
9775// before we get a chance to query it.
9776class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9777 public:
9778 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9779
9780 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9781
9782 protected:
9783 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9784 const HttpRequestInfo* request,
9785 const CompletionCallback& callback,
9786 std::string* auth_token) OVERRIDE {
9787 *url_ = request->url;
9788 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9789 credentials, request, callback, auth_token);
9790 }
9791
9792 private:
9793 GURL* url_;
9794};
9795
[email protected]23e482282013-06-14 16:08:029796TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309797 // This test ensures that the URL passed into the proxy is upgraded
9798 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389799 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439800 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309801
[email protected]bb88e1d32013-05-03 23:11:079802 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209803 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9804 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079805 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279806 GURL request_url;
9807 {
9808 HttpAuthHandlerMock::Factory* auth_factory =
9809 new HttpAuthHandlerMock::Factory();
9810 UrlRecordingHttpAuthHandlerMock* auth_handler =
9811 new UrlRecordingHttpAuthHandlerMock(&request_url);
9812 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9813 auth_factory->set_do_init_from_challenge(true);
9814 session_deps_.http_auth_handler_factory.reset(auth_factory);
9815 }
[email protected]f45c1ee2010-08-03 00:54:309816
9817 HttpRequestInfo request;
9818 request.method = "GET";
9819 request.url = GURL("http://www.google.com");
9820 request.load_flags = 0;
9821
9822 // First round goes unauthenticated through the proxy.
9823 MockWrite data_writes_1[] = {
9824 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9825 "Host: www.google.com\r\n"
9826 "Proxy-Connection: keep-alive\r\n"
9827 "\r\n"),
9828 };
9829 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069830 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309831 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239832 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309833 "Proxy-Connection: close\r\n"
9834 "\r\n"),
9835 };
9836 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9837 data_writes_1, arraysize(data_writes_1));
9838
9839 // Second round tries to tunnel to www.google.com due to the
9840 // Alternate-Protocol announcement in the first round. It fails due
9841 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599842 // After the failure, a tunnel is established to www.google.com using
9843 // Proxy-Authorization headers. There is then a SPDY request round.
9844 //
[email protected]fe3b7dc2012-02-03 19:52:099845 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9846 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9847 // does a Disconnect and Connect on the same socket, rather than trying
9848 // to obtain a new one.
9849 //
[email protected]394816e92010-08-03 07:38:599850 // NOTE: Originally, the proxy response to the second CONNECT request
9851 // simply returned another 407 so the unit test could skip the SSL connection
9852 // establishment and SPDY framing issues. Alas, the
9853 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309854 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599855
[email protected]cdf8f7e72013-05-23 10:56:469856 scoped_ptr<SpdyFrame> req(
9857 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029858 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9859 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309860
[email protected]394816e92010-08-03 07:38:599861 MockWrite data_writes_2[] = {
9862 // First connection attempt without Proxy-Authorization.
9863 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9864 "Host: www.google.com\r\n"
9865 "Proxy-Connection: keep-alive\r\n"
9866 "\r\n"),
9867
9868 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309869 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9870 "Host: www.google.com\r\n"
9871 "Proxy-Connection: keep-alive\r\n"
9872 "Proxy-Authorization: auth_token\r\n"
9873 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309874
[email protected]394816e92010-08-03 07:38:599875 // SPDY request
9876 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309877 };
[email protected]394816e92010-08-03 07:38:599878 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9879 "Proxy-Authenticate: Mock\r\n"
9880 "Proxy-Connection: close\r\n"
9881 "\r\n");
9882 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9883 MockRead data_reads_2[] = {
9884 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069885 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9886 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599887 arraysize(kRejectConnectResponse) - 1, 1),
9888
9889 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069890 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:099891 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:599892
9893 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:099894 CreateMockRead(*resp.get(), 6),
9895 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:069896 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:599897 };
[email protected]dd54bd82012-07-19 23:44:579898 OrderedSocketData data_2(
9899 data_reads_2, arraysize(data_reads_2),
9900 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:309901
[email protected]8ddf8322012-02-23 18:08:069902 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029903 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:309904
[email protected]d973e99a2012-02-17 21:02:369905 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559906 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9907 NULL, 0, NULL, 0);
9908 hanging_non_alternate_protocol_socket.set_connect_data(
9909 never_finishing_connect);
9910
[email protected]bb88e1d32013-05-03 23:11:079911 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9912 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9914 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559915 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:079916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:309917
9918 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:419919 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:369920 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:509921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419922 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309923 EXPECT_EQ(ERR_IO_PENDING, rv);
9924 EXPECT_EQ(OK, callback_1.WaitForResult());
9925
9926 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:419927 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:369928 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:509929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419930 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309931 EXPECT_EQ(ERR_IO_PENDING, rv);
9932 EXPECT_EQ(OK, callback_2.WaitForResult());
9933 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509934 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:309935 ASSERT_FALSE(response->auth_challenge.get() == NULL);
9936
9937 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:419938 TestCompletionCallback callback_3;
9939 rv = trans_2->RestartWithAuth(
9940 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:309941 EXPECT_EQ(ERR_IO_PENDING, rv);
9942 EXPECT_EQ(OK, callback_3.WaitForResult());
9943
9944 // After all that work, these two lines (or actually, just the scheme) are
9945 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:309946 EXPECT_EQ("https", request_url.scheme());
9947 EXPECT_EQ("www.google.com", request_url.host());
9948
[email protected]029c83b62013-01-24 05:28:209949 LoadTimingInfo load_timing_info;
9950 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9951 TestLoadTimingNotReusedWithPac(load_timing_info,
9952 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:389953}
9954
9955// Test that if we cancel the transaction as the connection is completing, that
9956// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:029957TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:389958 // Setup everything about the connection to complete synchronously, so that
9959 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9960 // for is the callback from the HttpStreamRequest.
9961 // Then cancel the transaction.
9962 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:369963 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:389964 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069965 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9966 MockRead(SYNCHRONOUS, "hello world"),
9967 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:389968 };
9969
[email protected]8e6441ca2010-08-19 05:56:389970 HttpRequestInfo request;
9971 request.method = "GET";
9972 request.url = GURL("http://www.google.com/");
9973 request.load_flags = 0;
9974
[email protected]bb88e1d32013-05-03 23:11:079975 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:079976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:279977 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:079978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:279979
[email protected]8e6441ca2010-08-19 05:56:389980 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9981 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079982 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:389983
[email protected]49639fa2011-12-20 23:22:419984 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:389985
[email protected]333bdf62012-06-08 22:57:299986 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:419987 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:389988 EXPECT_EQ(ERR_IO_PENDING, rv);
9989 trans.reset(); // Cancel the transaction here.
9990
[email protected]2da659e2013-05-23 20:51:349991 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:309992}
9993
[email protected]76a505b2010-08-25 06:23:009994// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029995TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:079996 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209997 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299998 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079999 session_deps_.net_log = log.bound().net_log();
10000 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010001
[email protected]76a505b2010-08-25 06:23:0010002 HttpRequestInfo request;
10003 request.method = "GET";
10004 request.url = GURL("http://www.google.com/");
10005
10006 MockWrite data_writes1[] = {
10007 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10008 "Host: www.google.com\r\n"
10009 "Proxy-Connection: keep-alive\r\n\r\n"),
10010 };
10011
10012 MockRead data_reads1[] = {
10013 MockRead("HTTP/1.1 200 OK\r\n"),
10014 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10015 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610016 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010017 };
10018
10019 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10020 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710021 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010022
[email protected]49639fa2011-12-20 23:22:4110023 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010024
[email protected]262eec82013-03-19 21:01:3610025 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010026 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010027
[email protected]49639fa2011-12-20 23:22:4110028 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010029 EXPECT_EQ(ERR_IO_PENDING, rv);
10030
10031 rv = callback1.WaitForResult();
10032 EXPECT_EQ(OK, rv);
10033
10034 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010035 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010036
10037 EXPECT_TRUE(response->headers->IsKeepAlive());
10038 EXPECT_EQ(200, response->headers->response_code());
10039 EXPECT_EQ(100, response->headers->GetContentLength());
10040 EXPECT_TRUE(response->was_fetched_via_proxy);
10041 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010042
10043 LoadTimingInfo load_timing_info;
10044 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10045 TestLoadTimingNotReusedWithPac(load_timing_info,
10046 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010047}
10048
10049// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210050TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710051 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010052 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910053 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710054 session_deps_.net_log = log.bound().net_log();
10055 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010056
[email protected]76a505b2010-08-25 06:23:0010057 HttpRequestInfo request;
10058 request.method = "GET";
10059 request.url = GURL("https://www.google.com/");
10060
10061 // Since we have proxy, should try to establish tunnel.
10062 MockWrite data_writes1[] = {
10063 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10064 "Host: www.google.com\r\n"
10065 "Proxy-Connection: keep-alive\r\n\r\n"),
10066
10067 MockWrite("GET / HTTP/1.1\r\n"
10068 "Host: www.google.com\r\n"
10069 "Connection: keep-alive\r\n\r\n"),
10070 };
10071
10072 MockRead data_reads1[] = {
10073 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10074
10075 MockRead("HTTP/1.1 200 OK\r\n"),
10076 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10077 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610078 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010079 };
10080
10081 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10082 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610084 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010086
[email protected]49639fa2011-12-20 23:22:4110087 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010088
[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]0b0bf032010-09-21 18:08:5010091
[email protected]49639fa2011-12-20 23:22:4110092 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010093 EXPECT_EQ(ERR_IO_PENDING, rv);
10094
10095 rv = callback1.WaitForResult();
10096 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710097 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010098 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010099 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010100 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010101 NetLog::PHASE_NONE);
10102 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010103 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010104 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10105 NetLog::PHASE_NONE);
10106
10107 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010108 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010109
10110 EXPECT_TRUE(response->headers->IsKeepAlive());
10111 EXPECT_EQ(200, response->headers->response_code());
10112 EXPECT_EQ(100, response->headers->GetContentLength());
10113 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10114 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:2010115
10116 LoadTimingInfo load_timing_info;
10117 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10118 TestLoadTimingNotReusedWithPac(load_timing_info,
10119 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010120}
10121
10122// Test a basic HTTPS GET request through a proxy, but the server hangs up
10123// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210124TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710125 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910126 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710127 session_deps_.net_log = log.bound().net_log();
10128 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010129
[email protected]76a505b2010-08-25 06:23:0010130 HttpRequestInfo request;
10131 request.method = "GET";
10132 request.url = GURL("https://www.google.com/");
10133
10134 // Since we have proxy, should try to establish tunnel.
10135 MockWrite data_writes1[] = {
10136 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10137 "Host: www.google.com\r\n"
10138 "Proxy-Connection: keep-alive\r\n\r\n"),
10139
10140 MockWrite("GET / HTTP/1.1\r\n"
10141 "Host: www.google.com\r\n"
10142 "Connection: keep-alive\r\n\r\n"),
10143 };
10144
10145 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610146 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010147 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610148 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010149 };
10150
10151 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10152 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710153 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610154 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010156
[email protected]49639fa2011-12-20 23:22:4110157 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010158
[email protected]262eec82013-03-19 21:01:3610159 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010160 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010161
[email protected]49639fa2011-12-20 23:22:4110162 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010163 EXPECT_EQ(ERR_IO_PENDING, rv);
10164
10165 rv = callback1.WaitForResult();
10166 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710167 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010168 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010169 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010170 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010171 NetLog::PHASE_NONE);
10172 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010173 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010174 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10175 NetLog::PHASE_NONE);
10176}
10177
[email protected]749eefa82010-09-13 22:14:0310178// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210179TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610180 scoped_ptr<SpdyFrame> req(
10181 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310182 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10183
[email protected]23e482282013-06-14 16:08:0210184 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10185 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310186 MockRead spdy_reads[] = {
10187 CreateMockRead(*resp),
10188 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610189 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310190 };
10191
[email protected]dd54bd82012-07-19 23:44:5710192 DelayedSocketData spdy_data(
10193 1, // wait for one write to finish before reading.
10194 spdy_reads, arraysize(spdy_reads),
10195 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710196 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310197
[email protected]8ddf8322012-02-23 18:08:0610198 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210199 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710200 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310201
[email protected]bb88e1d32013-05-03 23:11:0710202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310203
10204 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810205 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010206 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10207 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:2710208 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610209 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310210
10211 HttpRequestInfo request;
10212 request.method = "GET";
10213 request.url = GURL("https://www.google.com/");
10214 request.load_flags = 0;
10215
10216 // This is the important line that marks this as a preconnect.
10217 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10218
[email protected]262eec82013-03-19 21:01:3610219 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310221
[email protected]41d64e82013-07-03 22:44:2610222 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110223 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310224 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110225 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310226}
10227
[email protected]73b8dd222010-11-11 19:55:2410228// Given a net error, cause that error to be returned from the first Write()
10229// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210230void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710231 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710232 net::HttpRequestInfo request_info;
10233 request_info.url = GURL("https://www.example.com/");
10234 request_info.method = "GET";
10235 request_info.load_flags = net::LOAD_NORMAL;
10236
[email protected]8ddf8322012-02-23 18:08:0610237 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410238 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610239 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410240 };
10241 net::StaticSocketDataProvider data(NULL, 0,
10242 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710243 session_deps_.socket_factory->AddSocketDataProvider(&data);
10244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410245
[email protected]bb88e1d32013-05-03 23:11:0710246 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610247 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010248 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410249
[email protected]49639fa2011-12-20 23:22:4110250 TestCompletionCallback callback;
10251 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410252 if (rv == net::ERR_IO_PENDING)
10253 rv = callback.WaitForResult();
10254 ASSERT_EQ(error, rv);
10255}
10256
[email protected]23e482282013-06-14 16:08:0210257TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410258 // Just check a grab bag of cert errors.
10259 static const int kErrors[] = {
10260 ERR_CERT_COMMON_NAME_INVALID,
10261 ERR_CERT_AUTHORITY_INVALID,
10262 ERR_CERT_DATE_INVALID,
10263 };
10264 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610265 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10266 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410267 }
10268}
10269
[email protected]bd0b6772011-01-11 19:59:3010270// Ensure that a client certificate is removed from the SSL client auth
10271// cache when:
10272// 1) No proxy is involved.
10273// 2) TLS False Start is disabled.
10274// 3) The initial TLS handshake requests a client certificate.
10275// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210276TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310277 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710278 net::HttpRequestInfo request_info;
10279 request_info.url = GURL("https://www.example.com/");
10280 request_info.method = "GET";
10281 request_info.load_flags = net::LOAD_NORMAL;
10282
[email protected]bd0b6772011-01-11 19:59:3010283 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110284 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010285
10286 // [ssl_]data1 contains the data for the first SSL handshake. When a
10287 // CertificateRequest is received for the first time, the handshake will
10288 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610289 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010290 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710291 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010292 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710293 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010294
10295 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10296 // False Start is not being used, the result of the SSL handshake will be
10297 // returned as part of the SSLClientSocket::Connect() call. This test
10298 // matches the result of a server sending a handshake_failure alert,
10299 // rather than a Finished message, because it requires a client
10300 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610301 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010302 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710303 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010304 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710305 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010306
10307 // [ssl_]data3 contains the data for the third SSL handshake. When a
10308 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710309 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10310 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010311 // of the HttpNetworkTransaction. Because this test failure is due to
10312 // requiring a client certificate, this fallback handshake should also
10313 // fail.
[email protected]8ddf8322012-02-23 18:08:0610314 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010315 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010317 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710318 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010319
[email protected]80c75f682012-05-26 16:22:1710320 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10321 // connection to a server fails during an SSL handshake,
10322 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10323 // connection was attempted with TLSv1. This is transparent to the caller
10324 // of the HttpNetworkTransaction. Because this test failure is due to
10325 // requiring a client certificate, this fallback handshake should also
10326 // fail.
10327 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10328 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710330 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710331 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710332
[email protected]7799de12013-05-30 05:52:5110333 // Need one more if TLSv1.2 is enabled.
10334 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10335 ssl_data5.cert_request_info = cert_request.get();
10336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10337 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10338 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10339
[email protected]bb88e1d32013-05-03 23:11:0710340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610341 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010342 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010343
[email protected]bd0b6772011-01-11 19:59:3010344 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110345 TestCompletionCallback callback;
10346 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010347 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10348
10349 // Complete the SSL handshake, which should abort due to requiring a
10350 // client certificate.
10351 rv = callback.WaitForResult();
10352 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10353
10354 // Indicate that no certificate should be supplied. From the perspective
10355 // of SSLClientCertCache, NULL is just as meaningful as a real
10356 // certificate, so this is the same as supply a
10357 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110358 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010359 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10360
10361 // Ensure the certificate was added to the client auth cache before
10362 // allowing the connection to continue restarting.
10363 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110364 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10365 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010366 ASSERT_EQ(NULL, client_cert.get());
10367
10368 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710369 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10370 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010371 rv = callback.WaitForResult();
10372 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10373
10374 // Ensure that the client certificate is removed from the cache on a
10375 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110376 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10377 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010378}
10379
10380// Ensure that a client certificate is removed from the SSL client auth
10381// cache when:
10382// 1) No proxy is involved.
10383// 2) TLS False Start is enabled.
10384// 3) The initial TLS handshake requests a client certificate.
10385// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210386TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310387 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710388 net::HttpRequestInfo request_info;
10389 request_info.url = GURL("https://www.example.com/");
10390 request_info.method = "GET";
10391 request_info.load_flags = net::LOAD_NORMAL;
10392
[email protected]bd0b6772011-01-11 19:59:3010393 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110394 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010395
10396 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10397 // return successfully after reading up to the peer's Certificate message.
10398 // This is to allow the caller to call SSLClientSocket::Write(), which can
10399 // enqueue application data to be sent in the same packet as the
10400 // ChangeCipherSpec and Finished messages.
10401 // The actual handshake will be finished when SSLClientSocket::Read() is
10402 // called, which expects to process the peer's ChangeCipherSpec and
10403 // Finished messages. If there was an error negotiating with the peer,
10404 // such as due to the peer requiring a client certificate when none was
10405 // supplied, the alert sent by the peer won't be processed until Read() is
10406 // called.
10407
10408 // Like the non-False Start case, when a client certificate is requested by
10409 // the peer, the handshake is aborted during the Connect() call.
10410 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610411 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010412 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710413 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010414 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710415 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010416
10417 // When a client certificate is supplied, Connect() will not be aborted
10418 // when the peer requests the certificate. Instead, the handshake will
10419 // artificially succeed, allowing the caller to write the HTTP request to
10420 // the socket. The handshake messages are not processed until Read() is
10421 // called, which then detects that the handshake was aborted, due to the
10422 // peer sending a handshake_failure because it requires a client
10423 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610424 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010425 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010427 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610428 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010429 };
10430 net::StaticSocketDataProvider data2(
10431 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710432 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010433
10434 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710435 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10436 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610437 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010438 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710439 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010440 net::StaticSocketDataProvider data3(
10441 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710442 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010443
[email protected]80c75f682012-05-26 16:22:1710444 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10445 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10446 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10447 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710449 net::StaticSocketDataProvider data4(
10450 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710451 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710452
[email protected]7799de12013-05-30 05:52:5110453 // Need one more if TLSv1.2 is enabled.
10454 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10455 ssl_data5.cert_request_info = cert_request.get();
10456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10457 net::StaticSocketDataProvider data5(
10458 data2_reads, arraysize(data2_reads), NULL, 0);
10459 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10460
[email protected]bb88e1d32013-05-03 23:11:0710461 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610462 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010463 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010464
[email protected]bd0b6772011-01-11 19:59:3010465 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110466 TestCompletionCallback callback;
10467 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010468 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10469
10470 // Complete the SSL handshake, which should abort due to requiring a
10471 // client certificate.
10472 rv = callback.WaitForResult();
10473 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10474
10475 // Indicate that no certificate should be supplied. From the perspective
10476 // of SSLClientCertCache, NULL is just as meaningful as a real
10477 // certificate, so this is the same as supply a
10478 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110479 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010480 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10481
10482 // Ensure the certificate was added to the client auth cache before
10483 // allowing the connection to continue restarting.
10484 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110485 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10486 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010487 ASSERT_EQ(NULL, client_cert.get());
10488
[email protected]bd0b6772011-01-11 19:59:3010489 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710490 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10491 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010492 rv = callback.WaitForResult();
10493 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10494
10495 // Ensure that the client certificate is removed from the cache on a
10496 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110497 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10498 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010499}
10500
[email protected]8c405132011-01-11 22:03:1810501// Ensure that a client certificate is removed from the SSL client auth
10502// cache when:
10503// 1) An HTTPS proxy is involved.
10504// 3) The HTTPS proxy requests a client certificate.
10505// 4) The client supplies an invalid/unacceptable certificate for the
10506// proxy.
10507// The test is repeated twice, first for connecting to an HTTPS endpoint,
10508// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210509TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710510 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810511 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910512 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710513 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810514
10515 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110516 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810517
10518 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10519 // [ssl_]data[1-3]. Rather than represending the endpoint
10520 // (www.example.com:443), they represent failures with the HTTPS proxy
10521 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610522 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810523 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810525 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710526 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810527
[email protected]8ddf8322012-02-23 18:08:0610528 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810529 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810531 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710532 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810533
[email protected]80c75f682012-05-26 16:22:1710534 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10535#if 0
[email protected]8ddf8322012-02-23 18:08:0610536 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810537 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810539 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710540 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710541#endif
[email protected]8c405132011-01-11 22:03:1810542
10543 net::HttpRequestInfo requests[2];
10544 requests[0].url = GURL("https://www.example.com/");
10545 requests[0].method = "GET";
10546 requests[0].load_flags = net::LOAD_NORMAL;
10547
10548 requests[1].url = GURL("http://www.example.com/");
10549 requests[1].method = "GET";
10550 requests[1].load_flags = net::LOAD_NORMAL;
10551
10552 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710553 session_deps_.socket_factory->ResetNextMockIndexes();
10554 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810555 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810557
10558 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110559 TestCompletionCallback callback;
10560 int rv = trans->Start(
10561 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810562 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10563
10564 // Complete the SSL handshake, which should abort due to requiring a
10565 // client certificate.
10566 rv = callback.WaitForResult();
10567 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10568
10569 // Indicate that no certificate should be supplied. From the perspective
10570 // of SSLClientCertCache, NULL is just as meaningful as a real
10571 // certificate, so this is the same as supply a
10572 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110573 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810574 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10575
10576 // Ensure the certificate was added to the client auth cache before
10577 // allowing the connection to continue restarting.
10578 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110579 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10580 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810581 ASSERT_EQ(NULL, client_cert.get());
10582 // Ensure the certificate was NOT cached for the endpoint. This only
10583 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110584 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10585 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810586
10587 // Restart the handshake. This will consume ssl_data2, which fails, and
10588 // then consume ssl_data3, which should also fail. The result code is
10589 // checked against what ssl_data3 should return.
10590 rv = callback.WaitForResult();
10591 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10592
10593 // Now that the new handshake has failed, ensure that the client
10594 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110595 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10596 HostPortPair("proxy", 70), &client_cert));
10597 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10598 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810599 }
10600}
10601
[email protected]23e482282013-06-14 16:08:0210602// Unlike TEST/TEST_F, which are macros that expand to further macros,
10603// TEST_P is a macro that expands directly to code that stringizes the
10604// arguments. As a result, macros passed as parameters (such as prefix
10605// or test_case_name) will not be expanded by the preprocessor. To
10606// work around this, indirect the macro for TEST_P, so that the
10607// pre-processor will expand macros such as MAYBE_test_name before
10608// instantiating the test.
10609#define WRAPPED_TEST_P(test_case_name, test_name) \
10610 TEST_P(test_case_name, test_name)
10611
[email protected]45b170822012-05-04 21:18:1410612// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10613#if defined(OS_WIN)
10614#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10615#else
10616#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10617#endif
[email protected]23e482282013-06-14 16:08:0210618WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610619 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310620 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610621
10622 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710623 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610625 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10626 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610627
[email protected]8ddf8322012-02-23 18:08:0610628 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210629 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610631
[email protected]cdf8f7e72013-05-23 10:56:4610632 scoped_ptr<SpdyFrame> host1_req(
10633 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10634 scoped_ptr<SpdyFrame> host2_req(
10635 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610636 MockWrite spdy_writes[] = {
10637 CreateMockWrite(*host1_req, 1),
10638 CreateMockWrite(*host2_req, 4),
10639 };
[email protected]23e482282013-06-14 16:08:0210640 scoped_ptr<SpdyFrame> host1_resp(
10641 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10642 scoped_ptr<SpdyFrame> host1_resp_body(
10643 spdy_util_.ConstructSpdyBodyFrame(1, true));
10644 scoped_ptr<SpdyFrame> host2_resp(
10645 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10646 scoped_ptr<SpdyFrame> host2_resp_body(
10647 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610648 MockRead spdy_reads[] = {
10649 CreateMockRead(*host1_resp, 2),
10650 CreateMockRead(*host1_resp_body, 3),
10651 CreateMockRead(*host2_resp, 5),
10652 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610653 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610654 };
10655
[email protected]d2b5f092012-06-08 23:55:0210656 IPAddressNumber ip;
10657 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10658 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10659 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710660 OrderedSocketData spdy_data(
10661 connect,
10662 spdy_reads, arraysize(spdy_reads),
10663 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710664 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610665
[email protected]aa22b242011-11-16 18:58:2910666 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610667 HttpRequestInfo request1;
10668 request1.method = "GET";
10669 request1.url = GURL("https://www.google.com/");
10670 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010671 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610672
[email protected]49639fa2011-12-20 23:22:4110673 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610674 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110675 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610676
10677 const HttpResponseInfo* response = trans1.GetResponseInfo();
10678 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010679 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610680 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10681
10682 std::string response_data;
10683 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10684 EXPECT_EQ("hello!", response_data);
10685
10686 // Preload www.gmail.com into HostCache.
10687 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1010688 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4610689 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010690 rv = session_deps_.host_resolver->Resolve(resolve_info,
10691 DEFAULT_PRIORITY,
10692 &ignored,
10693 callback.callback(),
10694 NULL,
10695 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710696 EXPECT_EQ(ERR_IO_PENDING, rv);
10697 rv = callback.WaitForResult();
10698 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610699
10700 HttpRequestInfo request2;
10701 request2.method = "GET";
10702 request2.url = GURL("https://www.gmail.com/");
10703 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010704 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610705
[email protected]49639fa2011-12-20 23:22:4110706 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610707 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110708 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610709
10710 response = trans2.GetResponseInfo();
10711 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010712 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610713 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10714 EXPECT_TRUE(response->was_fetched_via_spdy);
10715 EXPECT_TRUE(response->was_npn_negotiated);
10716 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10717 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610718}
[email protected]45b170822012-05-04 21:18:1410719#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610720
[email protected]23e482282013-06-14 16:08:0210721TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210722 HttpStreamFactory::set_use_alternate_protocols(true);
10723 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10724
10725 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710726 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10727 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210728 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10729 pool_peer.DisableDomainAuthenticationVerification();
10730
10731 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210732 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710733 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210734
[email protected]cdf8f7e72013-05-23 10:56:4610735 scoped_ptr<SpdyFrame> host1_req(
10736 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10737 scoped_ptr<SpdyFrame> host2_req(
10738 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210739 MockWrite spdy_writes[] = {
10740 CreateMockWrite(*host1_req, 1),
10741 CreateMockWrite(*host2_req, 4),
10742 };
[email protected]23e482282013-06-14 16:08:0210743 scoped_ptr<SpdyFrame> host1_resp(
10744 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10745 scoped_ptr<SpdyFrame> host1_resp_body(
10746 spdy_util_.ConstructSpdyBodyFrame(1, true));
10747 scoped_ptr<SpdyFrame> host2_resp(
10748 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10749 scoped_ptr<SpdyFrame> host2_resp_body(
10750 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210751 MockRead spdy_reads[] = {
10752 CreateMockRead(*host1_resp, 2),
10753 CreateMockRead(*host1_resp_body, 3),
10754 CreateMockRead(*host2_resp, 5),
10755 CreateMockRead(*host2_resp_body, 6),
10756 MockRead(ASYNC, 0, 7),
10757 };
10758
10759 IPAddressNumber ip;
10760 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10761 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10762 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710763 OrderedSocketData spdy_data(
10764 connect,
10765 spdy_reads, arraysize(spdy_reads),
10766 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710767 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210768
10769 TestCompletionCallback callback;
10770 HttpRequestInfo request1;
10771 request1.method = "GET";
10772 request1.url = GURL("https://www.google.com/");
10773 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010774 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210775
10776 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10777 EXPECT_EQ(ERR_IO_PENDING, rv);
10778 EXPECT_EQ(OK, callback.WaitForResult());
10779
10780 const HttpResponseInfo* response = trans1.GetResponseInfo();
10781 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010782 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210783 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10784
10785 std::string response_data;
10786 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10787 EXPECT_EQ("hello!", response_data);
10788
10789 HttpRequestInfo request2;
10790 request2.method = "GET";
10791 request2.url = GURL("https://www.gmail.com/");
10792 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010793 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210794
10795 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10796 EXPECT_EQ(ERR_IO_PENDING, rv);
10797 EXPECT_EQ(OK, callback.WaitForResult());
10798
10799 response = trans2.GetResponseInfo();
10800 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010801 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210802 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10803 EXPECT_TRUE(response->was_fetched_via_spdy);
10804 EXPECT_TRUE(response->was_npn_negotiated);
10805 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10806 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210807}
10808
[email protected]e3ceb682011-06-28 23:55:4610809class OneTimeCachingHostResolver : public net::HostResolver {
10810 public:
10811 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10812 : host_port_(host_port) {}
10813 virtual ~OneTimeCachingHostResolver() {}
10814
10815 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10816
10817 // HostResolver methods:
10818 virtual int Resolve(const RequestInfo& info,
[email protected]5109c1952013-08-20 18:44:1010819 RequestPriority priority,
[email protected]e3ceb682011-06-28 23:55:4610820 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910821 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610822 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010823 const BoundNetLog& net_log) OVERRIDE {
10824 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1010825 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010826 }
10827
10828 virtual int ResolveFromCache(const RequestInfo& info,
10829 AddressList* addresses,
10830 const BoundNetLog& net_log) OVERRIDE {
10831 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10832 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910833 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610834 return rv;
10835 }
10836
[email protected]95a214c2011-08-04 21:50:4010837 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610838 host_resolver_.CancelRequest(req);
10839 }
10840
[email protected]46da33be2011-07-19 21:58:0410841 MockCachingHostResolver* GetMockHostResolver() {
10842 return &host_resolver_;
10843 }
10844
[email protected]e3ceb682011-06-28 23:55:4610845 private:
10846 MockCachingHostResolver host_resolver_;
10847 const HostPortPair host_port_;
10848};
10849
[email protected]45b170822012-05-04 21:18:1410850// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10851#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710852#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10853 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410854#else
[email protected]bb88e1d32013-05-03 23:11:0710855#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10856 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410857#endif
[email protected]23e482282013-06-14 16:08:0210858WRAPPED_TEST_P(HttpNetworkTransactionTest,
10859 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210860// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10861// prefix doesn't work with parametrized tests).
10862#if defined(OS_WIN)
10863 return;
10864#endif
10865
[email protected]e3ceb682011-06-28 23:55:4610866 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310867 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610868
10869 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610870 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410871 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710872 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610873 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710874 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610875 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10876 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610877
[email protected]8ddf8322012-02-23 18:08:0610878 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210879 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710880 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610881
[email protected]cdf8f7e72013-05-23 10:56:4610882 scoped_ptr<SpdyFrame> host1_req(
10883 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10884 scoped_ptr<SpdyFrame> host2_req(
10885 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610886 MockWrite spdy_writes[] = {
10887 CreateMockWrite(*host1_req, 1),
10888 CreateMockWrite(*host2_req, 4),
10889 };
[email protected]23e482282013-06-14 16:08:0210890 scoped_ptr<SpdyFrame> host1_resp(
10891 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10892 scoped_ptr<SpdyFrame> host1_resp_body(
10893 spdy_util_.ConstructSpdyBodyFrame(1, true));
10894 scoped_ptr<SpdyFrame> host2_resp(
10895 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10896 scoped_ptr<SpdyFrame> host2_resp_body(
10897 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610898 MockRead spdy_reads[] = {
10899 CreateMockRead(*host1_resp, 2),
10900 CreateMockRead(*host1_resp_body, 3),
10901 CreateMockRead(*host2_resp, 5),
10902 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610903 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610904 };
10905
[email protected]d2b5f092012-06-08 23:55:0210906 IPAddressNumber ip;
10907 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10908 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10909 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710910 OrderedSocketData spdy_data(
10911 connect,
10912 spdy_reads, arraysize(spdy_reads),
10913 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710914 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610915
[email protected]aa22b242011-11-16 18:58:2910916 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610917 HttpRequestInfo request1;
10918 request1.method = "GET";
10919 request1.url = GURL("https://www.google.com/");
10920 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010921 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610922
[email protected]49639fa2011-12-20 23:22:4110923 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610924 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110925 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610926
10927 const HttpResponseInfo* response = trans1.GetResponseInfo();
10928 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010929 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610930 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10931
10932 std::string response_data;
10933 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10934 EXPECT_EQ("hello!", response_data);
10935
10936 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1010937 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4610938 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1010939 rv = host_resolver.Resolve(resolve_info,
10940 DEFAULT_PRIORITY,
10941 &ignored,
10942 callback.callback(),
10943 NULL,
10944 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710945 EXPECT_EQ(ERR_IO_PENDING, rv);
10946 rv = callback.WaitForResult();
10947 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610948
10949 HttpRequestInfo request2;
10950 request2.method = "GET";
10951 request2.url = GURL("https://www.gmail.com/");
10952 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010953 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610954
[email protected]49639fa2011-12-20 23:22:4110955 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610956 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110957 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610958
10959 response = trans2.GetResponseInfo();
10960 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010961 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610962 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10963 EXPECT_TRUE(response->was_fetched_via_spdy);
10964 EXPECT_TRUE(response->was_npn_negotiated);
10965 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10966 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610967}
[email protected]45b170822012-05-04 21:18:1410968#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4610969
[email protected]23e482282013-06-14 16:08:0210970TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910971 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610972 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910973 };
10974 MockRead data_reads2[] = {
10975 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10976 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610977 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910978 };
10979 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10980 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10981 StaticSocketDataProvider* data[] = { &data1, &data2 };
10982
10983 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10984
10985 EXPECT_EQ(OK, out.rv);
10986 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10987 EXPECT_EQ("hello world", out.response_data);
10988}
10989
[email protected]23e482282013-06-14 16:08:0210990TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910991 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0610992 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910993 };
10994 MockWrite data_writes2[] = {
10995 MockWrite("GET / HTTP/1.1\r\n"
10996 "Host: www.google.com\r\n"
10997 "Connection: keep-alive\r\n\r\n"),
10998 };
10999 MockRead data_reads2[] = {
11000 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11001 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611002 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2911003 };
11004 StaticSocketDataProvider data1(NULL, 0,
11005 data_writes1, arraysize(data_writes1));
11006 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
11007 data_writes2, arraysize(data_writes2));
11008 StaticSocketDataProvider* data[] = { &data1, &data2 };
11009
11010 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
11011
11012 EXPECT_EQ(OK, out.rv);
11013 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
11014 EXPECT_EQ("hello world", out.response_data);
11015}
11016
[email protected]23e482282013-06-14 16:08:0211017TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0411018 const std::string https_url = "https://www.google.com/";
11019 const std::string http_url = "http://www.google.com:443/";
11020
11021 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611022 scoped_ptr<SpdyFrame> req1(
11023 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411024
11025 MockWrite writes1[] = {
11026 CreateMockWrite(*req1, 0),
11027 };
11028
[email protected]23e482282013-06-14 16:08:0211029 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11030 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411031 MockRead reads1[] = {
11032 CreateMockRead(*resp1, 1),
11033 CreateMockRead(*body1, 2),
11034 MockRead(ASYNC, ERR_IO_PENDING, 3)
11035 };
11036
[email protected]dd54bd82012-07-19 23:44:5711037 DelayedSocketData data1(
11038 1, reads1, arraysize(reads1),
11039 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411040 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711041 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411042
11043 // HTTP GET for the HTTP URL
11044 MockWrite writes2[] = {
11045 MockWrite(ASYNC, 4,
11046 "GET / HTTP/1.1\r\n"
11047 "Host: www.google.com:443\r\n"
11048 "Connection: keep-alive\r\n\r\n"),
11049 };
11050
11051 MockRead reads2[] = {
11052 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11053 MockRead(ASYNC, 6, "hello"),
11054 MockRead(ASYNC, 7, OK),
11055 };
11056
[email protected]dd54bd82012-07-19 23:44:5711057 DelayedSocketData data2(
11058 1, reads2, arraysize(reads2),
11059 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411060
[email protected]8450d722012-07-02 19:14:0411061 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211062 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11064 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11065 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411066
[email protected]bb88e1d32013-05-03 23:11:0711067 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411068
11069 // Start the first transaction to set up the SpdySession
11070 HttpRequestInfo request1;
11071 request1.method = "GET";
11072 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411073 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011074 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411075 TestCompletionCallback callback1;
11076 EXPECT_EQ(ERR_IO_PENDING,
11077 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411078 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411079
11080 EXPECT_EQ(OK, callback1.WaitForResult());
11081 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11082
11083 // Now, start the HTTP request
11084 HttpRequestInfo request2;
11085 request2.method = "GET";
11086 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411087 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011088 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411089 TestCompletionCallback callback2;
11090 EXPECT_EQ(ERR_IO_PENDING,
11091 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411092 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411093
11094 EXPECT_EQ(OK, callback2.WaitForResult());
11095 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11096}
11097
[email protected]23e482282013-06-14 16:08:0211098TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0411099 const std::string https_url = "https://www.google.com/";
11100 const std::string http_url = "http://www.google.com:443/";
11101
11102 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5411103 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11104 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611105 scoped_ptr<SpdyFrame> req1(
11106 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411107
11108 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0211109 scoped_ptr<SpdyFrame> wrapped_req1(
11110 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0411111 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0211112 spdy_util_.GetMethodKey(), "GET",
11113 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
11114 spdy_util_.GetHostKey(), "www.google.com:443",
11115 spdy_util_.GetSchemeKey(), "http",
11116 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0411117 };
[email protected]4bd46222013-05-14 19:32:2311118 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
11119 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
11120 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0411121
11122 MockWrite writes1[] = {
11123 CreateMockWrite(*connect, 0),
11124 CreateMockWrite(*wrapped_req1, 2),
11125 CreateMockWrite(*req2, 5),
11126 };
11127
[email protected]23e482282013-06-14 16:08:0211128 scoped_ptr<SpdyFrame> conn_resp(
11129 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11130 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11131 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11132 scoped_ptr<SpdyFrame> wrapped_resp1(
11133 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11134 scoped_ptr<SpdyFrame> wrapped_body1(
11135 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11136 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11137 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411138 MockRead reads1[] = {
11139 CreateMockRead(*conn_resp, 1),
11140 CreateMockRead(*wrapped_resp1, 3),
11141 CreateMockRead(*wrapped_body1, 4),
11142 CreateMockRead(*resp2, 6),
11143 CreateMockRead(*body2, 7),
11144 MockRead(ASYNC, ERR_IO_PENDING, 8)
11145 };
11146
[email protected]dd54bd82012-07-19 23:44:5711147 DeterministicSocketData data1(reads1, arraysize(reads1),
11148 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411149 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711150 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411151
[email protected]bb88e1d32013-05-03 23:11:0711152 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211153 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11154 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711155 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411156 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211157 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711158 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411159 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211160 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711161 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11162 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411163
11164 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711165 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411166
11167 // Start the first transaction to set up the SpdySession
11168 HttpRequestInfo request1;
11169 request1.method = "GET";
11170 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411171 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011172 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411173 TestCompletionCallback callback1;
11174 EXPECT_EQ(ERR_IO_PENDING,
11175 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411176 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711177 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411178
11179 EXPECT_EQ(OK, callback1.WaitForResult());
11180 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11181
[email protected]f6c63db52013-02-02 00:35:2211182 LoadTimingInfo load_timing_info1;
11183 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11184 TestLoadTimingNotReusedWithPac(load_timing_info1,
11185 CONNECT_TIMING_HAS_SSL_TIMES);
11186
[email protected]8450d722012-07-02 19:14:0411187 // Now, start the HTTP request
11188 HttpRequestInfo request2;
11189 request2.method = "GET";
11190 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411191 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011192 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411193 TestCompletionCallback callback2;
11194 EXPECT_EQ(ERR_IO_PENDING,
11195 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411196 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711197 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411198
11199 EXPECT_EQ(OK, callback2.WaitForResult());
11200 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211201
11202 LoadTimingInfo load_timing_info2;
11203 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11204 // The established SPDY sessions is considered reused by the HTTP request.
11205 TestLoadTimingReusedWithPac(load_timing_info2);
11206 // HTTP requests over a SPDY session should have a different connection
11207 // socket_log_id than requests over a tunnel.
11208 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411209}
11210
[email protected]23e482282013-06-14 16:08:0211211TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411212 HttpStreamFactory::set_force_spdy_always(true);
11213 const std::string https_url = "https://www.google.com/";
11214 const std::string http_url = "http://www.google.com:443/";
11215
11216 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611217 scoped_ptr<SpdyFrame> req1(
11218 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411219 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611220 scoped_ptr<SpdyFrame> req2(
11221 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411222
11223 MockWrite writes[] = {
11224 CreateMockWrite(*req1, 1),
11225 CreateMockWrite(*req2, 4),
11226 };
11227
[email protected]23e482282013-06-14 16:08:0211228 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11229 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11230 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11231 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411232 MockRead reads[] = {
11233 CreateMockRead(*resp1, 2),
11234 CreateMockRead(*body1, 3),
11235 CreateMockRead(*resp2, 5),
11236 CreateMockRead(*body2, 6),
11237 MockRead(ASYNC, ERR_IO_PENDING, 7)
11238 };
11239
[email protected]dd54bd82012-07-19 23:44:5711240 OrderedSocketData data(reads, arraysize(reads),
11241 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411242
[email protected]8450d722012-07-02 19:14:0411243 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211244 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11246 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411247
[email protected]bb88e1d32013-05-03 23:11:0711248 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411249
11250 // Start the first transaction to set up the SpdySession
11251 HttpRequestInfo request1;
11252 request1.method = "GET";
11253 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411254 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011255 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411256 TestCompletionCallback callback1;
11257 EXPECT_EQ(ERR_IO_PENDING,
11258 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411259 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411260
11261 EXPECT_EQ(OK, callback1.WaitForResult());
11262 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11263
11264 // Now, start the HTTP request
11265 HttpRequestInfo request2;
11266 request2.method = "GET";
11267 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411268 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011269 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411270 TestCompletionCallback callback2;
11271 EXPECT_EQ(ERR_IO_PENDING,
11272 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411273 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411274
11275 EXPECT_EQ(OK, callback2.WaitForResult());
11276 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11277}
11278
[email protected]2d88e7d2012-07-19 17:55:1711279// Test that in the case where we have a SPDY session to a SPDY proxy
11280// that we do not pool other origins that resolve to the same IP when
11281// the certificate does not match the new origin.
11282// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211283TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711284 const std::string url1 = "http://www.google.com/";
11285 const std::string url2 = "https://mail.google.com/";
11286 const std::string ip_addr = "1.2.3.4";
11287
11288 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211289 scoped_ptr<SpdyHeaderBlock> headers(
11290 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311291 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211292 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711293
11294 MockWrite writes1[] = {
11295 CreateMockWrite(*req1, 0),
11296 };
11297
[email protected]23e482282013-06-14 16:08:0211298 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11299 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711300 MockRead reads1[] = {
11301 CreateMockRead(*resp1, 1),
11302 CreateMockRead(*body1, 2),
11303 MockRead(ASYNC, OK, 3) // EOF
11304 };
11305
11306 scoped_ptr<DeterministicSocketData> data1(
11307 new DeterministicSocketData(reads1, arraysize(reads1),
11308 writes1, arraysize(writes1)));
11309 IPAddressNumber ip;
11310 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11311 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11312 MockConnect connect_data1(ASYNC, OK, peer_addr);
11313 data1->set_connect_data(connect_data1);
11314
11315 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611316 scoped_ptr<SpdyFrame> req2(
11317 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711318
11319 MockWrite writes2[] = {
11320 CreateMockWrite(*req2, 0),
11321 };
11322
[email protected]23e482282013-06-14 16:08:0211323 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11324 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711325 MockRead reads2[] = {
11326 CreateMockRead(*resp2, 1),
11327 CreateMockRead(*body2, 2),
11328 MockRead(ASYNC, OK, 3) // EOF
11329 };
11330
11331 scoped_ptr<DeterministicSocketData> data2(
11332 new DeterministicSocketData(reads2, arraysize(reads2),
11333 writes2, arraysize(writes2)));
11334 MockConnect connect_data2(ASYNC, OK);
11335 data2->set_connect_data(connect_data2);
11336
11337 // Set up a proxy config that sends HTTP requests to a proxy, and
11338 // all others direct.
11339 ProxyConfig proxy_config;
11340 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11341 CapturingProxyResolver* capturing_proxy_resolver =
11342 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711343 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711344 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11345 NULL));
11346
11347 // Load a valid cert. Note, that this does not need to
11348 // be valid for proxy because the MockSSLClientSocket does
11349 // not actually verify it. But SpdySession will use this
11350 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511351 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711352 scoped_refptr<X509Certificate> server_cert(
11353 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11354 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11355
11356 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211357 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711358 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711359 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11360 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11361 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711362
11363 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211364 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711365 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11366 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11367 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711368
[email protected]bb88e1d32013-05-03 23:11:0711369 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11370 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11371 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711372
11373 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711374 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711375
11376 // Start the first transaction to set up the SpdySession
11377 HttpRequestInfo request1;
11378 request1.method = "GET";
11379 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711380 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011381 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711382 TestCompletionCallback callback1;
11383 ASSERT_EQ(ERR_IO_PENDING,
11384 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11385 data1->RunFor(3);
11386
11387 ASSERT_TRUE(callback1.have_result());
11388 EXPECT_EQ(OK, callback1.WaitForResult());
11389 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11390
11391 // Now, start the HTTP request
11392 HttpRequestInfo request2;
11393 request2.method = "GET";
11394 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711395 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011396 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711397 TestCompletionCallback callback2;
11398 EXPECT_EQ(ERR_IO_PENDING,
11399 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411400 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711401 data2->RunFor(3);
11402
11403 ASSERT_TRUE(callback2.have_result());
11404 EXPECT_EQ(OK, callback2.WaitForResult());
11405 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11406}
11407
[email protected]85f97342013-04-17 06:12:2411408// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11409// error) in SPDY session, removes the socket from pool and closes the SPDY
11410// session. Verify that new url's from the same HttpNetworkSession (and a new
11411// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211412TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411413 const std::string https_url = "https://www.google.com/";
11414
11415 MockRead reads1[] = {
11416 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11417 };
11418
11419 scoped_ptr<DeterministicSocketData> data1(
11420 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11421 data1->SetStop(1);
11422
[email protected]cdf8f7e72013-05-23 10:56:4611423 scoped_ptr<SpdyFrame> req2(
11424 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411425 MockWrite writes2[] = {
11426 CreateMockWrite(*req2, 0),
11427 };
11428
[email protected]23e482282013-06-14 16:08:0211429 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11430 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411431 MockRead reads2[] = {
11432 CreateMockRead(*resp2, 1),
11433 CreateMockRead(*body2, 2),
11434 MockRead(ASYNC, OK, 3) // EOF
11435 };
11436
11437 scoped_ptr<DeterministicSocketData> data2(
11438 new DeterministicSocketData(reads2, arraysize(reads2),
11439 writes2, arraysize(writes2)));
11440
[email protected]85f97342013-04-17 06:12:2411441 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211442 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711443 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11444 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11445 data1.get());
[email protected]85f97342013-04-17 06:12:2411446
11447 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211448 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711449 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11450 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11451 data2.get());
[email protected]85f97342013-04-17 06:12:2411452
11453 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711454 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411455
11456 // Start the first transaction to set up the SpdySession and verify that
11457 // connection was closed.
11458 HttpRequestInfo request1;
11459 request1.method = "GET";
11460 request1.url = GURL(https_url);
11461 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011462 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411463 TestCompletionCallback callback1;
11464 EXPECT_EQ(ERR_IO_PENDING,
11465 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411466 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411467 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11468
11469 // Now, start the second request and make sure it succeeds.
11470 HttpRequestInfo request2;
11471 request2.method = "GET";
11472 request2.url = GURL(https_url);
11473 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011474 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411475 TestCompletionCallback callback2;
11476 EXPECT_EQ(ERR_IO_PENDING,
11477 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411478 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411479 data2->RunFor(3);
11480
11481 ASSERT_TRUE(callback2.have_result());
11482 EXPECT_EQ(OK, callback2.WaitForResult());
11483 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11484}
11485
[email protected]23e482282013-06-14 16:08:0211486TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311487 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11488 ClientSocketPoolManager::set_max_sockets_per_group(
11489 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11490 ClientSocketPoolManager::set_max_sockets_per_pool(
11491 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11492
11493 // Use two different hosts with different IPs so they don't get pooled.
11494 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11495 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11496 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11497
11498 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211499 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311500 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211501 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11504
[email protected]cdf8f7e72013-05-23 10:56:4611505 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311506 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11507 MockWrite spdy1_writes[] = {
11508 CreateMockWrite(*host1_req, 1),
11509 };
[email protected]23e482282013-06-14 16:08:0211510 scoped_ptr<SpdyFrame> host1_resp(
11511 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11512 scoped_ptr<SpdyFrame> host1_resp_body(
11513 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311514 MockRead spdy1_reads[] = {
11515 CreateMockRead(*host1_resp, 2),
11516 CreateMockRead(*host1_resp_body, 3),
11517 MockRead(ASYNC, ERR_IO_PENDING, 4),
11518 };
11519
11520 scoped_ptr<OrderedSocketData> spdy1_data(
11521 new OrderedSocketData(
11522 spdy1_reads, arraysize(spdy1_reads),
11523 spdy1_writes, arraysize(spdy1_writes)));
11524 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11525
[email protected]cdf8f7e72013-05-23 10:56:4611526 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311527 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11528 MockWrite spdy2_writes[] = {
11529 CreateMockWrite(*host2_req, 1),
11530 };
[email protected]23e482282013-06-14 16:08:0211531 scoped_ptr<SpdyFrame> host2_resp(
11532 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11533 scoped_ptr<SpdyFrame> host2_resp_body(
11534 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311535 MockRead spdy2_reads[] = {
11536 CreateMockRead(*host2_resp, 2),
11537 CreateMockRead(*host2_resp_body, 3),
11538 MockRead(ASYNC, ERR_IO_PENDING, 4),
11539 };
11540
11541 scoped_ptr<OrderedSocketData> spdy2_data(
11542 new OrderedSocketData(
11543 spdy2_reads, arraysize(spdy2_reads),
11544 spdy2_writes, arraysize(spdy2_writes)));
11545 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11546
11547 MockWrite http_write[] = {
11548 MockWrite("GET / HTTP/1.1\r\n"
11549 "Host: www.a.com\r\n"
11550 "Connection: keep-alive\r\n\r\n"),
11551 };
11552
11553 MockRead http_read[] = {
11554 MockRead("HTTP/1.1 200 OK\r\n"),
11555 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11556 MockRead("Content-Length: 6\r\n\r\n"),
11557 MockRead("hello!"),
11558 };
11559 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11560 http_write, arraysize(http_write));
11561 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11562
11563 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011564 SpdySessionKey spdy_session_key_a(
11565 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311566 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611567 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311568
11569 TestCompletionCallback callback;
11570 HttpRequestInfo request1;
11571 request1.method = "GET";
11572 request1.url = GURL("https://www.a.com/");
11573 request1.load_flags = 0;
11574 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011575 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311576
11577 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11578 EXPECT_EQ(ERR_IO_PENDING, rv);
11579 EXPECT_EQ(OK, callback.WaitForResult());
11580
11581 const HttpResponseInfo* response = trans->GetResponseInfo();
11582 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011583 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311584 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11585 EXPECT_TRUE(response->was_fetched_via_spdy);
11586 EXPECT_TRUE(response->was_npn_negotiated);
11587
11588 std::string response_data;
11589 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11590 EXPECT_EQ("hello!", response_data);
11591 trans.reset();
11592 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611593 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311594
11595 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011596 SpdySessionKey spdy_session_key_b(
11597 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311598 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611599 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311600 HttpRequestInfo request2;
11601 request2.method = "GET";
11602 request2.url = GURL("https://www.b.com/");
11603 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011604 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311605
11606 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11607 EXPECT_EQ(ERR_IO_PENDING, rv);
11608 EXPECT_EQ(OK, callback.WaitForResult());
11609
11610 response = trans->GetResponseInfo();
11611 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011612 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311613 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11614 EXPECT_TRUE(response->was_fetched_via_spdy);
11615 EXPECT_TRUE(response->was_npn_negotiated);
11616 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11617 EXPECT_EQ("hello!", response_data);
11618 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611619 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311620 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611621 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311622
11623 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011624 SpdySessionKey spdy_session_key_a1(
11625 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311626 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611627 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311628 HttpRequestInfo request3;
11629 request3.method = "GET";
11630 request3.url = GURL("http://www.a.com/");
11631 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011632 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311633
11634 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11635 EXPECT_EQ(ERR_IO_PENDING, rv);
11636 EXPECT_EQ(OK, callback.WaitForResult());
11637
11638 response = trans->GetResponseInfo();
11639 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011640 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311641 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11642 EXPECT_FALSE(response->was_fetched_via_spdy);
11643 EXPECT_FALSE(response->was_npn_negotiated);
11644 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11645 EXPECT_EQ("hello!", response_data);
11646 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611647 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311648 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611649 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311650}
11651
[email protected]79e1fd62013-06-20 06:50:0411652TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11653 HttpRequestInfo request;
11654 request.method = "GET";
11655 request.url = GURL("http://www.google.com/");
11656 request.load_flags = 0;
11657
[email protected]3fe8d2f82013-10-17 08:56:0711658 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411659 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411661
11662 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11663 StaticSocketDataProvider data;
11664 data.set_connect_data(mock_connect);
11665 session_deps_.socket_factory->AddSocketDataProvider(&data);
11666
11667 TestCompletionCallback callback;
11668
11669 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11670 EXPECT_EQ(ERR_IO_PENDING, rv);
11671
11672 rv = callback.WaitForResult();
11673 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11674
11675 EXPECT_EQ(NULL, trans->GetResponseInfo());
11676
11677 // We don't care whether this succeeds or fails, but it shouldn't crash.
11678 HttpRequestHeaders request_headers;
11679 trans->GetFullRequestHeaders(&request_headers);
11680}
11681
11682TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11683 HttpRequestInfo request;
11684 request.method = "GET";
11685 request.url = GURL("http://www.google.com/");
11686 request.load_flags = 0;
11687
[email protected]3fe8d2f82013-10-17 08:56:0711688 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411689 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711690 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411691
11692 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11693 StaticSocketDataProvider data;
11694 data.set_connect_data(mock_connect);
11695 session_deps_.socket_factory->AddSocketDataProvider(&data);
11696
11697 TestCompletionCallback callback;
11698
11699 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11700 EXPECT_EQ(ERR_IO_PENDING, rv);
11701
11702 rv = callback.WaitForResult();
11703 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11704
11705 EXPECT_EQ(NULL, trans->GetResponseInfo());
11706
11707 // We don't care whether this succeeds or fails, but it shouldn't crash.
11708 HttpRequestHeaders request_headers;
11709 trans->GetFullRequestHeaders(&request_headers);
11710}
11711
11712TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11713 HttpRequestInfo request;
11714 request.method = "GET";
11715 request.url = GURL("http://www.google.com/");
11716 request.load_flags = 0;
11717
[email protected]3fe8d2f82013-10-17 08:56:0711718 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411719 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711720 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411721
11722 MockWrite data_writes[] = {
11723 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11724 };
11725 MockRead data_reads[] = {
11726 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11727 };
11728
11729 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11730 data_writes, arraysize(data_writes));
11731 session_deps_.socket_factory->AddSocketDataProvider(&data);
11732
11733 TestCompletionCallback callback;
11734
11735 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11736 EXPECT_EQ(ERR_IO_PENDING, rv);
11737
11738 rv = callback.WaitForResult();
11739 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11740
11741 EXPECT_EQ(NULL, trans->GetResponseInfo());
11742
11743 HttpRequestHeaders request_headers;
11744 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11745 EXPECT_TRUE(request_headers.HasHeader("Host"));
11746}
11747
11748TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11749 HttpRequestInfo request;
11750 request.method = "GET";
11751 request.url = GURL("http://www.google.com/");
11752 request.load_flags = 0;
11753
[email protected]3fe8d2f82013-10-17 08:56:0711754 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411755 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711756 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411757
11758 MockWrite data_writes[] = {
11759 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11760 };
11761 MockRead data_reads[] = {
11762 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11763 };
11764
11765 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11766 data_writes, arraysize(data_writes));
11767 session_deps_.socket_factory->AddSocketDataProvider(&data);
11768
11769 TestCompletionCallback callback;
11770
11771 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11772 EXPECT_EQ(ERR_IO_PENDING, rv);
11773
11774 rv = callback.WaitForResult();
11775 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11776
11777 EXPECT_EQ(NULL, trans->GetResponseInfo());
11778
11779 HttpRequestHeaders request_headers;
11780 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11781 EXPECT_TRUE(request_headers.HasHeader("Host"));
11782}
11783
11784TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11785 HttpRequestInfo request;
11786 request.method = "GET";
11787 request.url = GURL("http://www.google.com/");
11788 request.load_flags = 0;
11789
[email protected]3fe8d2f82013-10-17 08:56:0711790 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411791 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711792 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411793
11794 MockWrite data_writes[] = {
11795 MockWrite("GET / HTTP/1.1\r\n"
11796 "Host: www.google.com\r\n"
11797 "Connection: keep-alive\r\n\r\n"),
11798 };
11799 MockRead data_reads[] = {
11800 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11801 };
11802
11803 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11804 data_writes, arraysize(data_writes));
11805 session_deps_.socket_factory->AddSocketDataProvider(&data);
11806
11807 TestCompletionCallback callback;
11808
11809 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11810 EXPECT_EQ(ERR_IO_PENDING, rv);
11811
11812 rv = callback.WaitForResult();
11813 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11814
11815 EXPECT_EQ(NULL, trans->GetResponseInfo());
11816
11817 HttpRequestHeaders request_headers;
11818 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11819 EXPECT_TRUE(request_headers.HasHeader("Host"));
11820}
11821
11822TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11823 HttpRequestInfo request;
11824 request.method = "GET";
11825 request.url = GURL("http://www.google.com/");
11826 request.load_flags = 0;
11827
[email protected]3fe8d2f82013-10-17 08:56:0711828 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411829 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711830 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411831
11832 MockWrite data_writes[] = {
11833 MockWrite("GET / HTTP/1.1\r\n"
11834 "Host: www.google.com\r\n"
11835 "Connection: keep-alive\r\n\r\n"),
11836 };
11837 MockRead data_reads[] = {
11838 MockRead(ASYNC, ERR_CONNECTION_RESET),
11839 };
11840
11841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11842 data_writes, arraysize(data_writes));
11843 session_deps_.socket_factory->AddSocketDataProvider(&data);
11844
11845 TestCompletionCallback callback;
11846
11847 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11848 EXPECT_EQ(ERR_IO_PENDING, rv);
11849
11850 rv = callback.WaitForResult();
11851 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11852
11853 EXPECT_EQ(NULL, trans->GetResponseInfo());
11854
11855 HttpRequestHeaders request_headers;
11856 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11857 EXPECT_TRUE(request_headers.HasHeader("Host"));
11858}
11859
11860TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11861 HttpRequestInfo request;
11862 request.method = "GET";
11863 request.url = GURL("http://www.google.com/");
11864 request.load_flags = 0;
11865 request.extra_headers.SetHeader("X-Foo", "bar");
11866
[email protected]3fe8d2f82013-10-17 08:56:0711867 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411868 scoped_ptr<HttpTransaction> trans(
[email protected]3fe8d2f82013-10-17 08:56:0711869 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]79e1fd62013-06-20 06:50:0411870
11871 MockWrite data_writes[] = {
11872 MockWrite("GET / HTTP/1.1\r\n"
11873 "Host: www.google.com\r\n"
11874 "Connection: keep-alive\r\n"
11875 "X-Foo: bar\r\n\r\n"),
11876 };
11877 MockRead data_reads[] = {
11878 MockRead("HTTP/1.1 200 OK\r\n"
11879 "Content-Length: 5\r\n\r\n"
11880 "hello"),
11881 MockRead(ASYNC, ERR_UNEXPECTED),
11882 };
11883
11884 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11885 data_writes, arraysize(data_writes));
11886 session_deps_.socket_factory->AddSocketDataProvider(&data);
11887
11888 TestCompletionCallback callback;
11889
11890 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11891 EXPECT_EQ(ERR_IO_PENDING, rv);
11892
11893 rv = callback.WaitForResult();
11894 EXPECT_EQ(OK, rv);
11895
11896 HttpRequestHeaders request_headers;
11897 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11898 std::string foo;
11899 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11900 EXPECT_EQ("bar", foo);
11901}
11902
[email protected]bf828982013-08-14 18:01:4711903namespace {
11904
[email protected]e86839fd2013-08-14 18:29:0311905// Fake HttpStreamBase that simply records calls to SetPriority().
11906class FakeStream : public HttpStreamBase,
11907 public base::SupportsWeakPtr<FakeStream> {
11908 public:
11909 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
11910 virtual ~FakeStream() {}
11911
11912 RequestPriority priority() const { return priority_; }
11913
11914 virtual int InitializeStream(const HttpRequestInfo* request_info,
11915 RequestPriority priority,
11916 const BoundNetLog& net_log,
11917 const CompletionCallback& callback) OVERRIDE {
11918 return ERR_IO_PENDING;
11919 }
11920
11921 virtual int SendRequest(const HttpRequestHeaders& request_headers,
11922 HttpResponseInfo* response,
11923 const CompletionCallback& callback) OVERRIDE {
11924 ADD_FAILURE();
11925 return ERR_UNEXPECTED;
11926 }
11927
11928 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
11929 ADD_FAILURE();
11930 return ERR_UNEXPECTED;
11931 }
11932
11933 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
11934 ADD_FAILURE();
11935 return NULL;
11936 }
11937
11938 virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
11939 const CompletionCallback& callback) OVERRIDE {
11940 ADD_FAILURE();
11941 return ERR_UNEXPECTED;
11942 }
11943
11944 virtual void Close(bool not_reusable) OVERRIDE {}
11945
11946 virtual bool IsResponseBodyComplete() const OVERRIDE {
11947 ADD_FAILURE();
11948 return false;
11949 }
11950
11951 virtual bool CanFindEndOfResponse() const OVERRIDE {
11952 return false;
11953 }
11954
11955 virtual bool IsConnectionReused() const OVERRIDE {
11956 ADD_FAILURE();
11957 return false;
11958 }
11959
11960 virtual void SetConnectionReused() OVERRIDE {
11961 ADD_FAILURE();
11962 }
11963
11964 virtual bool IsConnectionReusable() const OVERRIDE {
11965 ADD_FAILURE();
11966 return false;
11967 }
11968
[email protected]bc92bc972013-12-13 08:32:5911969 virtual int64 GetTotalReceivedBytes() const OVERRIDE {
11970 ADD_FAILURE();
11971 return 0;
11972 }
11973
[email protected]e86839fd2013-08-14 18:29:0311974 virtual bool GetLoadTimingInfo(
11975 LoadTimingInfo* load_timing_info) const OVERRIDE {
11976 ADD_FAILURE();
11977 return false;
11978 }
11979
11980 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
11981 ADD_FAILURE();
11982 }
11983
11984 virtual void GetSSLCertRequestInfo(
11985 SSLCertRequestInfo* cert_request_info) OVERRIDE {
11986 ADD_FAILURE();
11987 }
11988
11989 virtual bool IsSpdyHttpStream() const OVERRIDE {
11990 ADD_FAILURE();
11991 return false;
11992 }
11993
11994 virtual void Drain(HttpNetworkSession* session) OVERRIDE {
11995 ADD_FAILURE();
11996 }
11997
11998 virtual void SetPriority(RequestPriority priority) OVERRIDE {
11999 priority_ = priority;
12000 }
12001
12002 private:
12003 RequestPriority priority_;
12004
12005 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12006};
12007
12008// Fake HttpStreamRequest that simply records calls to SetPriority()
12009// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712010class FakeStreamRequest : public HttpStreamRequest,
12011 public base::SupportsWeakPtr<FakeStreamRequest> {
12012 public:
[email protected]e86839fd2013-08-14 18:29:0312013 FakeStreamRequest(RequestPriority priority,
12014 HttpStreamRequest::Delegate* delegate)
12015 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412016 delegate_(delegate),
12017 websocket_stream_create_helper_(NULL) {}
12018
12019 FakeStreamRequest(RequestPriority priority,
12020 HttpStreamRequest::Delegate* delegate,
12021 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12022 : priority_(priority),
12023 delegate_(delegate),
12024 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312025
[email protected]bf828982013-08-14 18:01:4712026 virtual ~FakeStreamRequest() {}
12027
12028 RequestPriority priority() const { return priority_; }
12029
[email protected]831e4a32013-11-14 02:14:4412030 const WebSocketHandshakeStreamBase::CreateHelper*
12031 websocket_stream_create_helper() const {
12032 return websocket_stream_create_helper_;
12033 }
12034
[email protected]e86839fd2013-08-14 18:29:0312035 // Create a new FakeStream and pass it to the request's
12036 // delegate. Returns a weak pointer to the FakeStream.
12037 base::WeakPtr<FakeStream> FinishStreamRequest() {
12038 FakeStream* fake_stream = new FakeStream(priority_);
12039 // Do this before calling OnStreamReady() as OnStreamReady() may
12040 // immediately delete |fake_stream|.
12041 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12042 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12043 return weak_stream;
12044 }
12045
[email protected]bf828982013-08-14 18:01:4712046 virtual int RestartTunnelWithProxyAuth(
12047 const AuthCredentials& credentials) OVERRIDE {
12048 ADD_FAILURE();
12049 return ERR_UNEXPECTED;
12050 }
12051
12052 virtual LoadState GetLoadState() const OVERRIDE {
12053 ADD_FAILURE();
12054 return LoadState();
12055 }
12056
12057 virtual void SetPriority(RequestPriority priority) OVERRIDE {
12058 priority_ = priority;
12059 }
12060
12061 virtual bool was_npn_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712062 return false;
12063 }
12064
12065 virtual NextProto protocol_negotiated() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712066 return kProtoUnknown;
12067 }
12068
12069 virtual bool using_spdy() const OVERRIDE {
[email protected]bf828982013-08-14 18:01:4712070 return false;
12071 }
12072
12073 private:
12074 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312075 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412076 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712077
12078 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12079};
12080
12081// Fake HttpStreamFactory that vends FakeStreamRequests.
12082class FakeStreamFactory : public HttpStreamFactory {
12083 public:
12084 FakeStreamFactory() {}
12085 virtual ~FakeStreamFactory() {}
12086
12087 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12088 // RequestStream() (which may be NULL if it was destroyed already).
12089 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12090 return last_stream_request_;
12091 }
12092
12093 virtual HttpStreamRequest* RequestStream(
12094 const HttpRequestInfo& info,
12095 RequestPriority priority,
12096 const SSLConfig& server_ssl_config,
12097 const SSLConfig& proxy_ssl_config,
12098 HttpStreamRequest::Delegate* delegate,
12099 const BoundNetLog& net_log) OVERRIDE {
[email protected]e86839fd2013-08-14 18:29:0312100 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712101 last_stream_request_ = fake_request->AsWeakPtr();
12102 return fake_request;
12103 }
12104
[email protected]a9cf2b92013-10-30 12:08:4912105 virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712106 const HttpRequestInfo& info,
12107 RequestPriority priority,
12108 const SSLConfig& server_ssl_config,
12109 const SSLConfig& proxy_ssl_config,
12110 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612111 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
[email protected]bf828982013-08-14 18:01:4712112 const BoundNetLog& net_log) OVERRIDE {
[email protected]831e4a32013-11-14 02:14:4412113 FakeStreamRequest* fake_request =
12114 new FakeStreamRequest(priority, delegate, create_helper);
12115 last_stream_request_ = fake_request->AsWeakPtr();
12116 return fake_request;
[email protected]bf828982013-08-14 18:01:4712117 }
12118
12119 virtual void PreconnectStreams(int num_streams,
12120 const HttpRequestInfo& info,
12121 RequestPriority priority,
12122 const SSLConfig& server_ssl_config,
12123 const SSLConfig& proxy_ssl_config) OVERRIDE {
12124 ADD_FAILURE();
12125 }
12126
12127 virtual base::Value* PipelineInfoToValue() const OVERRIDE {
12128 ADD_FAILURE();
12129 return NULL;
12130 }
12131
12132 virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
12133 ADD_FAILURE();
12134 return NULL;
12135 }
12136
12137 private:
12138 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12139
12140 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12141};
12142
[email protected]831e4a32013-11-14 02:14:4412143// TODO(yhirano): Split this class out into a net/websockets file, if it is
12144// worth doing.
12145class FakeWebSocketStreamCreateHelper :
12146 public WebSocketHandshakeStreamBase::CreateHelper {
12147 public:
12148 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112149 scoped_ptr<ClientSocketHandle> connection,
[email protected]831e4a32013-11-14 02:14:4412150 bool using_proxy) OVERRIDE {
12151 NOTREACHED();
12152 return NULL;
12153 }
12154
12155 virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12156 const base::WeakPtr<SpdySession>& session,
12157 bool use_relative_url) OVERRIDE {
12158 NOTREACHED();
12159 return NULL;
12160 };
12161
12162 virtual ~FakeWebSocketStreamCreateHelper() {}
12163
12164 virtual scoped_ptr<WebSocketStream> Upgrade() {
12165 NOTREACHED();
12166 return scoped_ptr<WebSocketStream>();
12167 }
12168};
12169
[email protected]bf828982013-08-14 18:01:4712170} // namespace
12171
12172// Make sure that HttpNetworkTransaction passes on its priority to its
12173// stream request on start.
12174TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12175 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12176 HttpNetworkSessionPeer peer(session);
12177 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412178 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712179
12180 HttpNetworkTransaction trans(LOW, session);
12181
12182 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12183
12184 HttpRequestInfo request;
12185 TestCompletionCallback callback;
12186 EXPECT_EQ(ERR_IO_PENDING,
12187 trans.Start(&request, callback.callback(), BoundNetLog()));
12188
12189 base::WeakPtr<FakeStreamRequest> fake_request =
12190 fake_factory->last_stream_request();
12191 ASSERT_TRUE(fake_request != NULL);
12192 EXPECT_EQ(LOW, fake_request->priority());
12193}
12194
12195// Make sure that HttpNetworkTransaction passes on its priority
12196// updates to its stream request.
12197TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12199 HttpNetworkSessionPeer peer(session);
12200 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412201 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712202
12203 HttpNetworkTransaction trans(LOW, session);
12204
12205 HttpRequestInfo request;
12206 TestCompletionCallback callback;
12207 EXPECT_EQ(ERR_IO_PENDING,
12208 trans.Start(&request, callback.callback(), BoundNetLog()));
12209
12210 base::WeakPtr<FakeStreamRequest> fake_request =
12211 fake_factory->last_stream_request();
12212 ASSERT_TRUE(fake_request != NULL);
12213 EXPECT_EQ(LOW, fake_request->priority());
12214
12215 trans.SetPriority(LOWEST);
12216 ASSERT_TRUE(fake_request != NULL);
12217 EXPECT_EQ(LOWEST, fake_request->priority());
12218}
12219
[email protected]e86839fd2013-08-14 18:29:0312220// Make sure that HttpNetworkTransaction passes on its priority
12221// updates to its stream.
12222TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12223 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12224 HttpNetworkSessionPeer peer(session);
12225 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412226 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312227
12228 HttpNetworkTransaction trans(LOW, session);
12229
12230 HttpRequestInfo request;
12231 TestCompletionCallback callback;
12232 EXPECT_EQ(ERR_IO_PENDING,
12233 trans.Start(&request, callback.callback(), BoundNetLog()));
12234
12235 base::WeakPtr<FakeStreamRequest> fake_request =
12236 fake_factory->last_stream_request();
12237 ASSERT_TRUE(fake_request != NULL);
12238 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12239 ASSERT_TRUE(fake_stream != NULL);
12240 EXPECT_EQ(LOW, fake_stream->priority());
12241
12242 trans.SetPriority(LOWEST);
12243 EXPECT_EQ(LOWEST, fake_stream->priority());
12244}
12245
[email protected]831e4a32013-11-14 02:14:4412246TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12247 // The same logic needs to be tested for both ws: and wss: schemes, but this
12248 // test is already parameterised on NextProto, so it uses a loop to verify
12249 // that the different schemes work.
12250 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12251 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12252 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12253 HttpNetworkSessionPeer peer(session);
12254 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12255 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312256 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412257 scoped_ptr<HttpStreamFactory>(fake_factory));
12258
12259 HttpNetworkTransaction trans(LOW, session);
12260 trans.SetWebSocketHandshakeStreamCreateHelper(
12261 &websocket_stream_create_helper);
12262
12263 HttpRequestInfo request;
12264 TestCompletionCallback callback;
12265 request.method = "GET";
12266 request.url = GURL(test_cases[i]);
12267
12268 EXPECT_EQ(ERR_IO_PENDING,
12269 trans.Start(&request, callback.callback(), BoundNetLog()));
12270
12271 base::WeakPtr<FakeStreamRequest> fake_request =
12272 fake_factory->last_stream_request();
12273 ASSERT_TRUE(fake_request != NULL);
12274 EXPECT_EQ(&websocket_stream_create_helper,
12275 fake_request->websocket_stream_create_helper());
12276 }
12277}
12278
[email protected]043b68c82013-08-22 23:41:5212279// Tests that when a used socket is returned to the SSL socket pool, it's closed
12280// if the transport socket pool is stalled on the global socket limit.
12281TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12282 ClientSocketPoolManager::set_max_sockets_per_group(
12283 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12284 ClientSocketPoolManager::set_max_sockets_per_pool(
12285 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12286
12287 // Set up SSL request.
12288
12289 HttpRequestInfo ssl_request;
12290 ssl_request.method = "GET";
12291 ssl_request.url = GURL("https://www.google.com/");
12292
12293 MockWrite ssl_writes[] = {
12294 MockWrite("GET / HTTP/1.1\r\n"
12295 "Host: www.google.com\r\n"
12296 "Connection: keep-alive\r\n\r\n"),
12297 };
12298 MockRead ssl_reads[] = {
12299 MockRead("HTTP/1.1 200 OK\r\n"),
12300 MockRead("Content-Length: 11\r\n\r\n"),
12301 MockRead("hello world"),
12302 MockRead(SYNCHRONOUS, OK),
12303 };
12304 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12305 ssl_writes, arraysize(ssl_writes));
12306 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12307
12308 SSLSocketDataProvider ssl(ASYNC, OK);
12309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12310
12311 // Set up HTTP request.
12312
12313 HttpRequestInfo http_request;
12314 http_request.method = "GET";
12315 http_request.url = GURL("http://www.google.com/");
12316
12317 MockWrite http_writes[] = {
12318 MockWrite("GET / HTTP/1.1\r\n"
12319 "Host: www.google.com\r\n"
12320 "Connection: keep-alive\r\n\r\n"),
12321 };
12322 MockRead http_reads[] = {
12323 MockRead("HTTP/1.1 200 OK\r\n"),
12324 MockRead("Content-Length: 7\r\n\r\n"),
12325 MockRead("falafel"),
12326 MockRead(SYNCHRONOUS, OK),
12327 };
12328 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12329 http_writes, arraysize(http_writes));
12330 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12331
12332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12333
12334 // Start the SSL request.
12335 TestCompletionCallback ssl_callback;
12336 scoped_ptr<HttpTransaction> ssl_trans(
12337 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12338 ASSERT_EQ(ERR_IO_PENDING,
12339 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12340 BoundNetLog()));
12341
12342 // Start the HTTP request. Pool should stall.
12343 TestCompletionCallback http_callback;
12344 scoped_ptr<HttpTransaction> http_trans(
12345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12346 ASSERT_EQ(ERR_IO_PENDING,
12347 http_trans->Start(&http_request, http_callback.callback(),
12348 BoundNetLog()));
12349 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12350
12351 // Wait for response from SSL request.
12352 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12353 std::string response_data;
12354 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12355 EXPECT_EQ("hello world", response_data);
12356
12357 // The SSL socket should automatically be closed, so the HTTP request can
12358 // start.
12359 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12360 ASSERT_FALSE(IsTransportSocketPoolStalled(session));
12361
12362 // The HTTP request can now complete.
12363 ASSERT_EQ(OK, http_callback.WaitForResult());
12364 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12365 EXPECT_EQ("falafel", response_data);
12366
12367 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12368}
12369
12370// Tests that when a SSL connection is established but there's no corresponding
12371// request that needs it, the new socket is closed if the transport socket pool
12372// is stalled on the global socket limit.
12373TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12374 ClientSocketPoolManager::set_max_sockets_per_group(
12375 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12376 ClientSocketPoolManager::set_max_sockets_per_pool(
12377 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12378
12379 // Set up an ssl request.
12380
12381 HttpRequestInfo ssl_request;
12382 ssl_request.method = "GET";
12383 ssl_request.url = GURL("https://www.foopy.com/");
12384
12385 // No data will be sent on the SSL socket.
12386 StaticSocketDataProvider ssl_data;
12387 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12388
12389 SSLSocketDataProvider ssl(ASYNC, OK);
12390 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12391
12392 // Set up HTTP request.
12393
12394 HttpRequestInfo http_request;
12395 http_request.method = "GET";
12396 http_request.url = GURL("http://www.google.com/");
12397
12398 MockWrite http_writes[] = {
12399 MockWrite("GET / HTTP/1.1\r\n"
12400 "Host: www.google.com\r\n"
12401 "Connection: keep-alive\r\n\r\n"),
12402 };
12403 MockRead http_reads[] = {
12404 MockRead("HTTP/1.1 200 OK\r\n"),
12405 MockRead("Content-Length: 7\r\n\r\n"),
12406 MockRead("falafel"),
12407 MockRead(SYNCHRONOUS, OK),
12408 };
12409 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12410 http_writes, arraysize(http_writes));
12411 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12412
12413 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12414
12415 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12416 // cancelled when a normal transaction is cancelled.
12417 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12418 net::SSLConfig ssl_config;
12419 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12420 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12421 ssl_config, ssl_config);
12422 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
12423
12424 // Start the HTTP request. Pool should stall.
12425 TestCompletionCallback http_callback;
12426 scoped_ptr<HttpTransaction> http_trans(
12427 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12428 ASSERT_EQ(ERR_IO_PENDING,
12429 http_trans->Start(&http_request, http_callback.callback(),
12430 BoundNetLog()));
12431 EXPECT_TRUE(IsTransportSocketPoolStalled(session));
12432
12433 // The SSL connection will automatically be closed once the connection is
12434 // established, to let the HTTP request start.
12435 ASSERT_EQ(OK, http_callback.WaitForResult());
12436 std::string response_data;
12437 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12438 EXPECT_EQ("falafel", response_data);
12439
12440 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
12441}
12442
[email protected]89ceba9a2009-03-21 03:46:0612443} // namespace net