http_network_transaction_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_transaction.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h>  // ceil
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/weak_ptr.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_file_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/capturing_net_log.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info_test_util.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/request_priority.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_data_directory.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_file_element_reader.h"
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/mock_cert_verifier.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/dns/host_cache.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_digest.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_mock.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_ntlm.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_basic_stream.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session_peer.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_server_properties_impl.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_transaction_unittest.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_fixed.h"
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/proxy/proxy_info.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_service.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h"
53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/socket/client_socket_pool_manager.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/mock_client_socket_pool_manager.h"
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_test_util.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_framer.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h"
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/spdy/spdy_test_util_common.h"
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/ssl/ssl_config_service.h"
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_config_service_defaults.h"
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_info.h"
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/cert_test_util.h"
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/websockets/websocket_handshake_stream_base.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "url/gurl.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16;
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar(ASCIIToUTF16("bar"));
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar2(ASCIIToUTF16("bar2"));
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar3(ASCIIToUTF16("bar3"));
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBaz(ASCIIToUTF16("baz"));
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFirst(ASCIIToUTF16("first"));
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo(ASCIIToUTF16("foo"));
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo2(ASCIIToUTF16("foo2"));
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo3(ASCIIToUTF16("foo3"));
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFou(ASCIIToUTF16("fou"));
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kSecond(ASCIIToUTF16("second"));
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetTransportSocketPool(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetSSLSocketPool(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return session->GetTransportSocketPool(
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes in a Value created from a NetLogHttpResponseParameter, and returns
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a JSONified list of headers as a single string.  Uses single quotes instead
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of double quotes for easier comparison.  Returns false on failure.
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::ListValue* header_list;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->GetList("headers", &header_list))
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string double_quote_headers;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(header_list, &double_quote_headers);
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::ReplaceChars(double_quote_headers, "\"", "'", headers);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.send_start.is_null());
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int connect_timing_flags) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   connect_timing_flags);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    int connect_timing_flags) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   connect_timing_flags);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SpdySessionDependencies::SpdyCreateSession(session_deps);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HttpNetworkTransactionTest
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public PlatformTest,
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      public ::testing::WithParamInterface<NextProto> {
225a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) public:
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~HttpNetworkTransactionTest() {
227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Important to restore the per-pool limit first, since the pool limit must
228a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // always be greater than group limit, and the tests reduce both limits.
229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_pool(
230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_group(
232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HttpNetworkTransactionTest()
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      : spdy_util_(GetParam()),
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        session_deps_(GetParam()),
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)),
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)) {
243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SimpleGetHelperResult {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status_line;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 totalReceivedBytes;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Empty the current queue.
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformTest::TearDown();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HttpStreamFactory::set_use_alternate_protocols(false);
267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This is the expected return from a current server advertising SPDY.
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string GetAlternateProtocolHttpHeader() {
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        std::string("Alternate-Protocol: 443:") +
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "\r\n\r\n";
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either |write_failure| specifies a write failure or |read_failure|
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specifies a read failure when using a reused socket.  In either case, the
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // failure should cause the network transaction to resend the request, and the
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other argument should be NULL.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const MockRead* read_failure);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               size_t data_count) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CapturingBoundNetLog log;
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.net_log = log.bound().net_log();
2968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < data_count; ++i) {
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(data[i]);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(log.bound().IsLoggingAllEvents());
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), log.bound());
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = callback.WaitForResult();
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Even in the failure cases that use this function, connections are always
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // successfully established before the error.
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (out.rv != OK)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Can't use ASSERT_* inside helper functions like this, so
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // return an error.
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (response == NULL || response->headers.get() == NULL) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.rv = ERR_UNEXPECTED;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.status_line = response->headers->GetStatusLine();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ("127.0.0.1", response->socket_address.host());
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(80, response->socket_address.port());
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &out.response_data);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::CapturingNetLog::CapturedEntryList entries;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.GetEntries(&entries);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t pos = ExpectLogContainsSomewhere(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectLogContainsSomewhere(
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, pos,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string line;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("GET / HTTP/1.1\r\n", line);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpRequestHeaders request_headers;
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string value;
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Host", &value));
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("www.google.com", value);
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("keep-alive", value);
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string response_headers;
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              response_headers);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out.totalReceivedBytes = trans->GetTotalReceivedBytes();
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        size_t reads_count) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider* data[] = { &reads };
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SimpleGetHelperForData(data, 1);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 size = 0;
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < reads_count; ++i)
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      size += data_reads[i].data_len;
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return size;
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int expected_status);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelper(const MockRead& status);
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void BypassHostCacheOnRefreshHelper(int load_flags);
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CheckErrorIsPassedBack(int error, IoMode mode);
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
389a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SpdyTestUtil spdy_util_;
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionDependencies session_deps_;
391a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
392a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Original socket limits.  Some tests set these.  Safest to always restore
393a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // them once each test has been run.
394a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_group_sockets_;
395a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_pool_sockets_;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NextProto,
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    HttpNetworkTransactionTest,
4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    testing::Values(kProtoDeprecatedSPDY2,
4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
403558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                    kProtoHTTP2Draft04));
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BeforeNetworkStartHandler {
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit BeforeNetworkStartHandler(bool defer)
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : defer_on_before_network_start_(defer),
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        observed_before_network_start_(false) {}
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnBeforeNetworkStart(bool* defer) {
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *defer = defer_on_before_network_start_;
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    observed_before_network_start_ = true;
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool observed_before_network_start() const {
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return observed_before_network_start_;
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const bool defer_on_before_network_start_;
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool observed_before_network_start_;
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fill |str| with a long header list that consumes >= |size| bytes.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillLargeHeadersString(std::string* str, int size) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* row =
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_row = strlen(row);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int num_rows = static_cast<int>(
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ceil(static_cast<float>(size) / sizeof_row));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_data = num_rows * sizeof_row;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(sizeof_data >= size);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  str->reserve(sizeof_data);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < num_rows; ++i)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str->append(row, sizeof_row);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alternative functions that eliminate randomness and dependency on the local
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// host name so that the generated NTLM messages are reproducible.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom1(uint8* output, size_t n) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom2(uint8* output, size_t n) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MockGetHostName() {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "WTC-WIN7";
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CaptureGroupNameSocketPool : public ParentPool {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureGroupNameSocketPool(HostResolver* host_resolver,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CertVerifier* cert_verifier);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string last_group_name_received() const {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return last_group_name_;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int RequestSocket(const std::string& group_name,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const void* socket_params,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            RequestPriority priority,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ClientSocketHandle* handle,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const CompletionCallback& callback,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const BoundNetLog& net_log) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_group_name_ = group_name;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_IO_PENDING;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(const std::string& group_name,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ClientSocketHandle* handle) {}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseSocket(const std::string& group_name,
4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             scoped_ptr<StreamSocket> socket,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int id) {}
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CloseIdleSockets() {}
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCount() const {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCountInGroup(const std::string& group_name) const {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(const std::string& group_name,
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const ClientSocketHandle* handle) const {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta ConnectionTimeout() const {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string last_group_name_;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameTransportSocketPool;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSOCKSSocketPool;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier)
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : SSLClientSocketPool(0,
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          0,
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          host_resolver,
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          cert_verifier,
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          NULL,
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          std::string(),
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL) {}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for validating that AuthChallengeInfo's are correctly
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// configured for common cases.
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(auth_challenge->is_proxy);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digestive", auth_challenge->realm);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digest", auth_challenge->scheme);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(), auth_challenge->realm);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("ntlm", auth_challenge->scheme);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Basic) {
6048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGET) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Response with no status line.
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Beyond 4 bytes of slop and it should fail to find a status line.
6707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
6857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Q"),
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("J"),
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Close the connection before enough bytes to have a status line.
7047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTT"),
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTT", out.response_data);
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulate a 204 response, lacking a Content-Length header, sent over a
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// persistent connection.  The response should still terminate since a 204
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cannot have a response body.
7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StopsReading204) {
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  char junk[] = "junk";
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(junk),  // Should not be read!!
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", out.response_data);
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - strlen(junk);
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple request using chunked encoding with some extra data after.
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (Like might be seen in a pipelined response.)
7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string final_chunk = "0\r\n\r\n";
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extra_data = "HTTP/1.1 200 OK\r\n";
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string last_read = final_chunk + extra_data;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(last_read.data()),
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - extra_data.size();
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/56344.
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersNoTransferEncoding) {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n"),
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DuplicateContentLengthHeadersNoTransferEncoding) {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n"),
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ComplexContentLengthHeadersNoTransferEncoding) {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More than 2 dupes.
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP/1.0
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 dupes and one mismatched.
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersTransferEncoding) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 666\r\n"),
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1337\r\n"),
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Transfer-Encoding: chunked\r\n\r\n"),
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/98895.
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that a single Content-Disposition header results in no error.
8627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Content-Disposition headers result in no error.
8777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       TwoIdenticalContentDispositionHeaders) {
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Content-Disposition headers result in an error.
8947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Location headers result in no error.
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also tests Location header behavior.
9097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://redirect.com/");
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://good.com/", url);
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Location headers result in an error.
9467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://evil.com/\r\n"),
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Do a request using the HEAD method. Verify that we don't try to read the
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message body (since HEAD has none).
9617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Head) {
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Server: Blah\r\n"),
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1234\r\n\r\n"),
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the headers got parsed.
1002868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1234, response->headers->GetContentLength());
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_header;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* iter = NULL;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_server_header = response->headers->EnumerateHeader(
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &iter, "Server", &server_header);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(has_server_header);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Blah", server_header);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reading should give EOF right away, since there is no message body
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (despite non-zero content-length).
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExpectedResponseData[] = {
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores100) {
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
107168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is almost the same as Ignores100 above, but the response contains
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTP/1.1 and the two status headers are read in one read.
11157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HTTP/1.1 200 OK\r\n\r\n"),
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* write_failure,
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* read_failure) {
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Written data for successfully sending both requests.
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data1_writes[] = {
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read results for the first request.
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_failure) {
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(!read_failure);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_writes[1] = *write_failure;
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(read_failure);
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_reads[2] = *read_failure;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data1_writes, arraysize(data1_writes));
1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The second request should be using a new socket.
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       KeepAliveConnectionNotConnectedOnWrite) {
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(&write_failure, NULL);
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
13248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What do various browsers do when the server closes a non-keepalive
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection without sending any response header or body?
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IE7: error page
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Safari 3.1.2 (Windows): error page
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Firefox 3.0.1: blank page
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opera 9.52: after five attempts, blank page
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us: error page (EMPTY_RESPONSE)
13567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // EOF
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network access can be deferred and resumed.
13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
13705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
13715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
13725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
13735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
13745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
13805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
13825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
13835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
13845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MockRead data_reads[] = {
13865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
13875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
13885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("hello"),
13895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
13905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
13915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
13935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
13955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
13985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
13995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
14015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
14025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
14035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
14045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->ResumeNetworkStart();
14065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = callback.WaitForResult();
14075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
14085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() != NULL);
14095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
14115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
14125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
14135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = callback.WaitForResult();
14145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(5, rv);
14155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans.reset();
14165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network use can be deferred and canceled.
14195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
14205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
14215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
14225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
14235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
14245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
14275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
14305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
14315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
14325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
14335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
14345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
14365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
14395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
14405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
14425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
14435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
14445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
14455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests. There was a bug causing HttpNetworkTransaction to hang in the
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor in such situations.
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/154712 and http://crbug.com/156609.
14517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, rv);
1484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
148890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
152690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we correctly reuse a keep-alive connection after not explicitly
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reading the body.
15327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that because all these reads happen in the same
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StaticSocketDataProvider, it shows that the same socket is being reused for
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all transactions.
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumUnreadBodies = arraysize(data1_reads) - 2;
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_lines[kNumUnreadBodies];
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingReused(load_timing_info);
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(response->headers.get() != NULL);
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_lines[i] = response->headers->GetStatusLine();
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We intentionally don't read the response bodies.
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kStatusLines[] = {
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 204 No Content",
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 205 Reset Content",
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 304 Not Modified",
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 forgot_to_update_kStatusLines);
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumUnreadBodies; ++i)
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kStatusLines[i], response_lines[i]);
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
1631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello", response_data);
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth.
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (basic auth is the easiest to mock, because it has no randomness).
16417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuth) {
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
16498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
16518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
1693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
17095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
17105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have a new socket ID, and times after
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.connect_timing.connect_start);
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
17345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
17355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
17508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
1769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
17795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
17805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection.
17887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
1796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a regression where we disconnect a Keep-Alive
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection during an auth roundtrip, we'll end up reading this.
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
1835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have the same socket ID, and times
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.send_start);
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
18785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string response_data;
18805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
18815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
18835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with no response body to drain.
18887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
1930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with a large response body to drain.
19647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 5 kb of response body.
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_body_string("Unauthorized");
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append(5 * 1024, ' ');
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append("\r\n");
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 5134 = 12 + 5 * 1024 + 2
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5134\r\n\r\n"),
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection, but the server gets impatient and closes the connection.
20487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This simulates the seemingly successful write to a closed connection
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if the bug is not fixed.
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tell MockTCPClientSocket to simulate the server closing the connection.
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
2100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a connection
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that requires a restart when setting up an SSL tunnel.
21347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
21432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello"),
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
22162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT requests and responses are handled at the connect job level, so
22172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the transaction does not yet have a connection.
22182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
22192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
22412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
22422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
22432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy connection, when setting up an SSL tunnel.
22507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that proxy authentication is attempted even
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0123456789"),
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong credentials (wrong password).
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrong password (should be "bar").
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBaz), callback2.callback());
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the NetLog and HttpNetworkTransaction go
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // out of scope.
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't read the response body when we fail to establish a tunnel,
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// even if the user cancels the proxy's auth attempt.
23547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407.
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
2385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
24137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are using a DIRECT connection (i.e. no proxy) for this session.
24208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
24228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through a non-authenticating proxy. The request should fail with
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ERR_UNEXPECTED_PROXY_AUTH.
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that it is impossible to detect if an HTTP server returns a 407 through
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a non-authenticating proxy - there is nothing to indicate whether the
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// response came from the proxy or the server, so it is treated as if the proxy
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// issued the challenge.
24587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       HttpsServerRequestsProxyAuthThroughProxy) {
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Unauthorized\r\n"),
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\n"),
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy.
25177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
25182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
25192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
25202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
25212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
25232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
25242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
25252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
25282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("PROXY myproxy:70"));
25292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
25342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
25352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
25362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
25372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
25402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
25462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
25472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
25502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
25542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
25552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
25562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
25582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
25592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
25602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
25612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
25632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
25672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
25692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
25732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
25762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
25772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
25792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
25812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
25822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
25842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
25852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
25862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
25882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
25902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
25942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
25972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
25982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
26002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
26022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
26032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
26052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
26062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
26072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
26092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
26112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
26122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
26132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
26157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
26162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
26172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
26182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
26192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
26212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
26222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
26232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
26262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
26272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
26322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
26332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
26342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
26352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
26362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
26382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
26392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
26402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
26422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
26432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
26442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
26452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
26472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
26482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
26492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
26502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
26522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
26532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
26542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
26562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
26572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
26582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
26592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
26612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
26652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
26672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
26692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
26712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
26742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
26752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
26772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
26792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
26802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
26822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
26832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
26842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
26852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
26872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
26892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
26912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
26932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
26962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
26972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
26992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
27012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
27022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
27042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
27052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
27062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
27082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
27102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
27112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a simple get through an HTTPS Proxy.
27147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
27582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
27592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
27602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
27612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
27757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch http://www.google.com/ via SPDY
278990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
279090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
27947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
28087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
28232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
28242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
28252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
28262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
28387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
2845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request will be a bare GET, the second request will be a
28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GET with a Proxy-Authorization header.
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get(
285490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthorizationHeaders[] = {
285690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authorization", "Basic Zm9vOmJhcg=="
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get_authorization(
285990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
286090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  arraysize(kExtraAuthorizationHeaders) / 2,
286190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false,
286290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  3,
286390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  LOWEST,
286490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false));
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get, 1),
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get_authorization, 4),
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first response is a 407 proxy authentication challenge, and the second
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response will be a 200 response since the second request includes a valid
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Authorization header.
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthenticationHeaders[] = {
287490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\""
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_authentication(
28777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError(
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "407 Proxy Authentication Required",
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1));
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_authentication(
28827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
28837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_data(
28847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
28857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_authentication, 2),
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_authentication, 3),
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_data, 5),
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_data, 6),
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
29007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response = trans->GetResponseInfo();
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response_restart != NULL);
2934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response_restart->headers.get() != NULL);
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response_restart->headers->response_code());
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
29417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
29583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
29593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
29667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
29677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
29687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 10\r\n\r\n";
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
29727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
29747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
297690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
298190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateMockWrite(*window_update, 5),
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 7, ASYNC),
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
29987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.was_npn_negotiated = false;
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
30142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
30152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
30162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1234567890", response_data);
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
30287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
30453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
30463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via SPDY
30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kMyUrl = "https://www.google.com/";
304990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
305090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
30517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
30527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get, 1));
30537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
30547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp(
30567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
30587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
30597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
30607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
30617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body, 1));
30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_get_resp(
306390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_body(
306590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_get_resp, 5),
30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_body, 7),
30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
30877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
30907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
30917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.protocol_negotiated = GetParam();
3092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
31032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
31042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
31052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT failure through an HTTPS Proxy.
31177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
31343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
31353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
313690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
313790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*get, 3),
31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
31457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 2, ASYNC),
31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),
31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
31577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
31607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
3161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
31752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to different servers.
31767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
31772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
31782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
31802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
31812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
31832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
31852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
31872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
31882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
31892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
31902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
31922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
31932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://news.google.com/");
31942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
31952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
31973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
31983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
31997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
32007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
32012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
32032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
32042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
32052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
32062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
32077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
32082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
32092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
32102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
32117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
32127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
32137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
32142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
321590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
32162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to news.google.com:443 via SPDY.
32182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* const kConnectHeaders2[] = {
32197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetMethodKey(), "CONNECT",
32207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetPathKey(), "news.google.com:443",
32217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetHostKey(), "news.google.com",
32227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetVersionKey(), "HTTP/1.1",
32232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
32242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(
3225a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      spdy_util_.ConstructSpdyControlFrame(NULL,
3226a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0,
3227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           /*compressed*/ false,
3228a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           3,
3229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           LOWEST,
3230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           SYN_STREAM,
3231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           CONTROL_FLAG_NONE,
3232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           kConnectHeaders2,
3233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           arraysize(kConnectHeaders2),
3234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0));
32357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp2(
32367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
32372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://news.google.com/ via HTTP.
32392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET / HTTP/1.1\r\n"
32402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: news.google.com\r\n"
32412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
32422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
32437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
32442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
32452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
32462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
32477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
32482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
32497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
32502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
32522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
32532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
32542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect2, 5),
32552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 7),
32562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
32572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
32592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
32602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
32612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
32622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp2, 6, ASYNC),
32632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
32642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 9, ASYNC),
32652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 10),
32662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
32672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
32692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
32702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
32722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
32747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
32762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
32772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
32782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
32802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl3(ASYNC, OK);
32812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.was_npn_negotiated = false;
32822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.protocol_negotiated = kProtoUnknown;
3283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
32842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
32862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
32902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
32922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
32932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
32952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
32962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
32982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
32992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
33002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
33022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
33042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
33052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
33072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
33092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
33122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
33132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
33142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second connect and request, each of their responses, and the body.
33162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
33172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
33182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
33192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
33212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
33222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Even though the SPDY connection is reused, a new tunnelled connection has
33232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to be created, so the socket's load timing looks like a fresh connection.
33242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
33252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have different IDs, since they each are using their own
33272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // separate stream.
33282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
33292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
33312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
33322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
33342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to the same server.
33357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
33362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
33372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
33392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
33402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
33422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
33442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
33462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
33472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
33482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
33492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
33512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
33522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
33532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
33542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
33563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
33573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
33587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
33597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
33622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
33632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
33642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
33652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
33667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
33672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
33682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
33692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
33707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
33717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
33727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
33732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
337490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
33752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/2 via HTTP.
33772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET /2 HTTP/1.1\r\n"
33782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
33792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
33802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
33817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
33822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
33832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
33842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
33857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
33862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
33877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
33882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
33902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
33912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
33922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 5),
33932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
33942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
33962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
33972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
33982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
33992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
34002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 7, ASYNC),
34012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 8),
34022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
34032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
34052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
34062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
34082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
34107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
34122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
34132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
34142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
34162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
34182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
34212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
34222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
34242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
34252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
34272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
34282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
34302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
34312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
34322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
34342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
34362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
34372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
34392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
34412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
34422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
34452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
34462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second request, response, and body.  There should not be a second
34492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connect.
34502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(3);
34512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
34522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
34532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
34552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
34562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
34572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
34592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
34602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
34622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
34632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
34652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Proxy to different servers.
34667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
34672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyLoadTimingTwoHttpRequests) {
34682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
34702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
34712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
34732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
34752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
34772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
34782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("http://www.google.com/");
34792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
34802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
34822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
34832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("http://news.google.com/");
34842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
34852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://www.google.com/
34877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
34887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
34907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
34917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp1(
34927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
34937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(
34947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
34952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://news.google.com/
34977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers2(
34987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3499a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
35007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
35017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp2(
35027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
35037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(
35047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
35052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
35072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get1, 0),
35082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get2, 3),
35092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
35122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp1, 1, ASYNC),
35132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body1, 2, ASYNC),
35142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp2, 4, ASYNC),
35152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body2, 5, ASYNC),
35162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 6),
35172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
35202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
35212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
35232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
35257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
35272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
35292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
35322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
35332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
35342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
35352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
35372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
35382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
35402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
35412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
35422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
35432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
35452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
35472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
35482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
35502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
35522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
35532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, callback.WaitForResult());
35542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete the first request, so the second one can reuse the socket.
35552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
35562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
35592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
35602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
35612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
35632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
35642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
35652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
35672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
35682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
35692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
35712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
35722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
35742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
35752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, callback.WaitForResult());
35762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
35772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the challenge-response-retry sequence through an HTTPS Proxy
35797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the GET with a 407, using a persistent
36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: keep-alive\r\n"),
36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
3624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
3626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
36402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
36412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
36422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
36432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  load_timing_info = LoadTimingInfo();
36612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
36622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Retrying with HTTP AUTH is considered to be reusing a socket.
36632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info);
36642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status, int expected_status) {
36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
3685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status,
36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
3704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_status, rv);
37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelper(
37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status) {
37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status, ERR_TUNNEL_CONNECTION_FAILED);
37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ERR_PROXY_AUTH_UNSUPPORTED);
38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the flow when both the proxy server AND origin server require
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authentication. Again, this uses basic auth for both since that is
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the simplest to mock.
38917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
3898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
38998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
39028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Unauthorized\r\n"),
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the first time, this is the
39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request we should be issuing -- the final header line contains the
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy's credentials.
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the proxy server lets the request pass through to origin server.
39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin server responds with a 401.
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: We are using the same realm-name as the proxy server. This is
39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // completely valid, as realms are unique across hosts.
39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 2000\r\n\r\n"),
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the second time, we should send
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the credentials for both the proxy and origin server.
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly we get the desired content.
39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
3969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
3970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
3971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo2, kBar2), callback3.callback());
40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NTLM implementation using SSPI, we skip the NTLM tests since we
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can't hook into its internals to cause it to generate predictable NTLM
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authorization headers.
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE)
40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The NTLM authentication unit tests were generated by capturing the HTTP
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests and responses using Fiddler 2 and inspecting the generated random
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes in the debugger.
40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter the correct password and authenticate successfully.
40217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
40254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
40264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Ensure load is not disrupted by flags which suppress behaviour specific
40274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to other auth schemes.
40284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ahlhx5I=\r\n\r\n"),
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
4103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter a wrong password, and then the correct one.
41537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "4Ww7b7E=\r\n\r\n"),
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong password.
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "+4MUm7c=\r\n\r\n"),
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enter the wrong password.
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now enter the right password.
43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback4.callback());
43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback5;
43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One more roundtrip
43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback5.WaitForResult();
43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NTLM_PORTABLE
43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test reading a server response which has only headers, and no body.
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After some maximum number of bytes is consumed, the transaction should
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
43557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
43638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 300 kb of headers (we should fail after 256 kb).
43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_headers_string;
43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillLargeHeadersString(&large_headers_string, 300 * 1024);
43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\nBODY"),
43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we don't try to reuse a TCPClientSocket when failing to
43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// establish tunnel.
43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/chromium/issues/detail?id=3772
43937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DontRecycleTransportSocketForSSLTunnel) {
43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
4401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 404, using a persistent
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection. Usually a proxy would return 501 (not implemented),
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or 200 (tunnel established).
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
4426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
444190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the TCPClientSocket was not added back to
44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool.
4445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
444790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the socket didn't get recycled after calling the destructor.
4449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after reading all of the response body.
44537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A part of the response body is received with the response headers.
44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The rest of the response body is received in two parts.
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("lo"),
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" world"),
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", status_line);
44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
450190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a SSL socket after reading all of the response
45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// body.
45097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
4529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
45382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
456090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the pool and make sure that we recover okay.
45687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0)   // EOF
45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
4593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
4601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
46062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
462890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start the second transaction, which should reuse the previous socket.
46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
465590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
46595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after a zero-length response.
46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/9880
46637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "e=17259,18167,19592,19773,19981,20133,20173,20233&"
46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "rt=prt.2642,ol.2649,xjs.2951");
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n"
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n"
46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html\r\n\r\n"),
46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
471290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
47192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
47202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
472168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
47222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request[2];
47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: a GET request that succeeds.  The socket is recycled
47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after use.
47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].method = "GET";
47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].url = GURL("http://www.google.com/");
47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].load_flags = 0;
47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: a POST request.  Reuses the socket kept alive from
47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 1.  The first attempts fails when writing the POST data.
47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This causes the transaction to retry with a new socket.  The second
47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempt succeeds.
47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].method = "POST";
47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].url = GURL("http://www.google.com/login.cgi");
47352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request[1].upload_data_stream = &upload_data_stream;
47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].load_flags = 0;
47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first socket is used for transaction 1 and the first attempt of
47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 1.
47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of transaction 1 and the first attempt of
47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 64),  // GET
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second socket is used for the second attempt of transaction 2.
47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 2.
47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("welcome"),
47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of the second attempt of transaction 2.
47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 3),  // POST data
47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello world", "welcome"
47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
4784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is
48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an identity in the URL. The request should be sent as normal, but when
48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it fails the identity from the URL is used to answer the challenge.
48107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:b@r@www.google.com/");
48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
48188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password contains an escaped character -- for this test to pass it
48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will need to be unescaped by HttpNetworkTransaction.
48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("b%40r", request.url.password());
48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
48355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, b@r) to answer the challenge.
48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
4856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity in URL worked.
48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
488290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is an
48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// incorrect identity in the URL. The identity from the URL should be used only
48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once.
48887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: the URL has a username:password in it.  The password "baz" is
48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wrong (should be "bar").
48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:baz@www.google.com/");
48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
48998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, baz) to answer the challenge.
49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity supplied by the user (foo, bar) to answer the challenge.
49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
49565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
49705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
49845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity worked.
49875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
49885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
499290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
49964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is a
49974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// correct identity in the URL, but its use is being suppressed. The identity
49984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// from the URL should never be used.
49994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
50004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
50014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "GET";
50024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://foo:bar@www.google.com/");
50034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
50044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
50064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
50078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
50084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes1[] = {
50104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
50114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
50124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
50134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
50144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads1[] = {
50164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
50174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
50184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
50194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
50204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
50214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
50234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // identity supplied by the user, not the one in the URL, to answer the
50244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // challenge.
50254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes3[] = {
50264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
50274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
50284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n"
50294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
50304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
50314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads3[] = {
50334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
50344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
50354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
50364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
50374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
50394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
50404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
50414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
50424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
50434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
50444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback1;
50464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
50474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
50484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback1.WaitForResult();
50494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
50504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
50514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
50534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
50544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
50554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback3;
50574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = trans->RestartWithAuth(
50584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
50594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
50604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback3.WaitForResult();
50614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
50624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
50634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  response = trans->GetResponseInfo();
50654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
50664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // There is no challenge info, since the identity worked.
50684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
50694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
50704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Empty the current queue.
50724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
50734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
50744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that previously tried username/passwords for a realm get re-used.
50767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
5077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
50805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
50825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
50845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
50935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
51065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
51085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
51125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
51145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
51465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: authenticate (foo2, bar2) on MyRealm2
51545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as MyRealm1.
51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
51645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
51665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
51675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
51685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
51695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // Send preemptive authorization for MyRealm1
51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The server didn't like the preemptive authorization, and
51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // challenges us for a different realm (MyRealm2).
51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
51785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
51805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
51845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
51865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
51875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
51885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
51915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
51935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
51955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
51985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
51995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
52005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
52035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response->auth_challenge.get());
52155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(response->auth_challenge->is_proxy);
52165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("www.google.com:80",
52175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              response->auth_challenge->challenger.ToString());
52185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
52195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("basic", response->auth_challenge->scheme);
52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo2, kBar2), callback2.callback());
52255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
52265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 3: Resend a request in MyRealm's protection space --
52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // succeed with preemptive authorization.
52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z2");
52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
52485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
52505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
52515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // The authorization for MyRealm1 gets sent preemptively
52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // (since the url is in the same protection space)
52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the preemptive authorization
52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
52615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
52625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
52635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
52645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
52665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
52685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
52705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
52725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
52735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
52755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
52785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
52795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
52815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
52825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
52835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
52855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 4: request another URL in MyRealm (however the
52875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url is not known to belong to the protection space, so no pre-auth).
52885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
52895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
52905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
52915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/1");
52925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
52935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
52965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
52985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
52995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
53015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
53045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
53075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
53085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from MyRealm's cache.
53115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
53125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
53135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
53155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
53165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
53195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
53205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
53215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
53225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
53235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
53265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
53275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
53285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
53315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
53335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
53355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
53365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
53385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
53395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
53415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
53425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
53435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
53445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
53455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
53465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
53475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
53495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
53505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
53515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
53525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
53535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
53555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 5: request a URL in MyRealm, but the server rejects the
53575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cached identity. Should invalidate and re-prompt.
53585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
53595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
53605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
53615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/p/q/t");
53625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
53635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
53665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
53685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
53695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
53715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
53745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
53775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
53785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from cache for MyRealm.
53815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
53825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
53835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
53855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
53865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever rejects the authorization.
53895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
53935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
53945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // At this point we should prompt for new credentials for MyRealm.
53975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart with username=foo3, password=foo4.
53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes3[] = {
53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
54065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads3[] = {
54075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
54155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
54165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
54175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes3, arraysize(data_writes3));
5418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
5420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data3);
54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
54255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
54285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
54325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
54335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
54355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
54415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback3;
54435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo3, kBar3), callback3.callback());
54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback3.WaitForResult();
54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that nonce count increments when multiple auth attempts
54595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are started with the same nonce.
54607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
54615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::Factory* digest_factory =
54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::Factory();
54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  digest_factory->set_nonce_generator(nonce_generator);
5466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(digest_factory);
5467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
54685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
54865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
54875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
54885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
54895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
54945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
54985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
54995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
55005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
55125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
55225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
55405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
55435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: Request another resource in digestive's protection space.
55455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will preemptively add an Authorization header which should have an
55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "nc" value of 2 (as compared to 1 in the first use.
55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as digest.
55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
55545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
55605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
55625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
55635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
55655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
55765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
55785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
55855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
55905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the ResetStateForRestart() private method.
55947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
55955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a transaction (the dependencies aren't important).
55968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
55988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup some state (which we expect ResetStateForRestart() will clear).
56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_ = new IOBuffer(15);
56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_len_ = 15;
56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->request_headers_.SetHeader("Authorization", "NTLM");
56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup state in response_
56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpResponseInfo* response = &trans->response_;
56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->auth_challenge = new AuthChallengeInfo();
56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->response_time = base::Time::Now();
56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->was_cached = true;  // (Wouldn't ever actually be true...)
56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { // Setup state for response_.vary_data
56135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
56145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
56155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::replace(temp.begin(), temp.end(), '\n', '\0');
56165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("Foo", "1");
56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("bar", "23");
5619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
56205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cause the above state to be reset.
56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->ResetStateForRestart();
56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the state that needed to be reset, has been reset.
56265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->read_buf_.get() == NULL);
56275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, trans->read_buf_len_);
56285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->request_headers_.IsEmpty());
56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
56305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() == NULL);
56315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_cached);
56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, response->ssl_info.cert_status);
56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->vary_data.is_valid());
56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate
56377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
56385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
56395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
56405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
56415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
56425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
56445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
56458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
56465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
56485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
56495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
56505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
56515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
56545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
56555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
56565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
56575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate;
56615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
56625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
56705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
56835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
56845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
56865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through a
56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy
56937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
56955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
56975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
56985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite proxy_writes[] = {
57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
57035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
57045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
57145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
57155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
57165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
57175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
57225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
57245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_reads, arraysize(proxy_reads),
57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_writes, arraysize(proxy_writes));
57325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
57335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
57345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
57365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
57435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
5745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
57465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
57485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
57498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
57505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
57525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
57555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
57565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartIgnoringLastError(callback.callback());
57585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
57615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
57645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
57675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
57685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site, going through an HTTPS proxy
57727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
5773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
57742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
57752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
5776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
57775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
57795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
57805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
57825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
57855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
57865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
57875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
57885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
57895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
57905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
57935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
57945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
57955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
57965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
57985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
58015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
58025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
58035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
58045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
58085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
58105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
58125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
58138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
58145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
58165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
58175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
58205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
58215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
58255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
58265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
58275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
58282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
58302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
58312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
58322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
58335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
58345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS Proxy's ability to redirect a CONNECT request
58367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
5837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
58382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
58392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
5840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
58415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
58435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
58445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
58455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
58465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
58485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
58495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
58505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
58515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
58525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
58545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
58555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://login.example.com/\r\n"),
58565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
58575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
58585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
58595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
58615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
58625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
58705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
58718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
58725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
58745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
58755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
58775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
58785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
58795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
58815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
58835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
58845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
58855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
58862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In the case of redirects from proxies, HttpNetworkTransaction returns
58882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timing for the proxy connection instead of the connection to the host,
58892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and no send / receive times.
58902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
58912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
58922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
58932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
58952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
58962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
58982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
58992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
59002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
59012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
59022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectConnectTimingHasTimes(
59032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      load_timing_info.connect_timing,
59042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
59052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
59062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_start.is_null());
59072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_end.is_null());
59082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
59095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
59127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
5913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
59145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
59155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
59223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
592390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> goaway(
592490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
59255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
59265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
5927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
59325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
59335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
59357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
59365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
59375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
59385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
59395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2),  // EOF
59405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
59435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
59445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
59455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
59465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
59477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
59485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
59515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
59535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
59555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
59568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
59575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
59595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
59625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
59635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
59645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
59665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
59685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
59695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
59705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
59715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an HTTPS proxy's response to a CONNECT request is filtered.
59747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
59755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaHttpsProxy) {
5976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
59775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
59785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
59855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
59865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
59875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
59885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
59915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
59925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 23\r\n\r\n"),
59935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("The host does not exist"),
59945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
59955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
59985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
59995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
60005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
60035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
60055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
60075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
60088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
60095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
60115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
60125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
60145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
60155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
60175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a SPDY proxy's response to a CONNECT request is filtered.
60207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
60215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaSpdyProxy) {
6022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
6023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     ProxyService::CreateFixed("https://proxy:70"));
60245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
60265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
60275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
60285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
60295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
60313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
603290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
603390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
60345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
60355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
60365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
60375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
60405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
60415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
60425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
60447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
60455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
60465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(
60477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(
60487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          1, "The host does not exist", 23, true));
60495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
60505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
60515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body.get(), 2, SYNCHRONOUS),
60525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),  // EOF
60535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
60565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
60575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
60585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
60595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
60607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
60615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
60645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
60665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
60685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
60698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
60705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
60725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
60735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
60765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
60785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, through
60815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a SPDY proxy over a single SPDY session.
60827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
60835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
60845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
60855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
60865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
60875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
60885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
60912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
60925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
6094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
60955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
60973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
60983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                            LOWEST));
609990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
610090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
61015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
61035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
61045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthCredentials[] = {
61055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-authorization", "Basic Zm9vOmJhcg==",
61065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
610790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
61083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
61095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
61105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
61115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
61125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
61135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
61147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
61155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
61175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 1, ASYNC),
61185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 4, ASYNC),
61195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect2, 5),
61205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_get, 8),
61215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
61245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
61255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthChallenge[] = {
61267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
61277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetVersionKey(), "HTTP/1.1",
61285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\"",
61295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_auth_resp(
6132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      spdy_util_.ConstructSpdyControlFrame(NULL,
6133a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0,
6134a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           false,
6135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           1,
6136a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           LOWEST,
6137a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           SYN_REPLY,
6138a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           CONTROL_FLAG_NONE,
6139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           kAuthChallenge,
6140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           arraysize(kAuthChallenge),
6141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0));
61425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
61447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
61455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
61465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 5\r\n\r\n";
61475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
61497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
61505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
61517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
61525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
61535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_auth_resp, 2, ASYNC),
61545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 6, ASYNC),
61555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 9, ASYNC),
61565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 10, ASYNC),
61575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
61585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
61615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
61625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
61645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
61655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
61667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
61685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vanilla SSL to the server
61695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider server(ASYNC, OK);
6170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
61715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
61735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
61765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
61785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
61795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
61815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
61835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
61845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
61855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
61865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
61875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
61885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
61895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
61905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
61915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
61935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
6194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
61955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
61965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
61975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() != NULL);
61985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
61995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
62015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
62035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
62045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
62075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
62085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
62105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
62115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
62135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
62145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
62155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
62165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
62185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
62195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
62212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
62222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
62232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
62242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
62265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
62275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy can push a resource from an
62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// origin that is different from that of its associated resource.
62317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
62325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo push_request;
62345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.method = "GET";
62385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.url = GURL("http://www.another-origin.com/foo.dat");
62395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
62422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
62435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
62455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
62485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
62505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
625290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
62535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
625590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
62565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
62597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
62605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
62627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
62657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
62665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
62675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
62685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
62695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "http://www.another-origin.com/foo.dat"));
6270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char kPushedData[] = "pushed";
6271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> stream2_body(
6272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(
6273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          2, kPushedData, strlen(kPushedData), true));
62745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
62765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
62775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
62785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 4, ASYNC),
6279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockRead(*stream2_body, 5, ASYNC),
62805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
62815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
62845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
62855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
62875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
62885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
62897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
62915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
62965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
63005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
63015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> push_trans(
6303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = push_trans->Start(&push_request, callback.callback(), log.bound());
63055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
63095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
63105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
63125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
63135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
63155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
63165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
63185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
63195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
63205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
63215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
63232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
63242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
63252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
63262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
63275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the pushed stream.
6328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(push_response->headers.get() != NULL);
63295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, push_response->headers->response_code());
63305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(push_trans.get(), &response_data);
63325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
63335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("pushed", response_data);
63345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo push_load_timing_info;
63362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
63372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(push_load_timing_info);
63382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transactions should share a socket ID, despite being for different
63392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // origins.
63402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id,
63412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            push_load_timing_info.socket_log_id);
63422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
63435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
63445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_trans.reset();
63455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
63465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
63497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
63505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
63545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
63575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
63585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
63605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
63635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
636690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
636790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
63685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> push_rst(
637090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
63715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
63735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
63745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*push_rst, 4),
63755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
63787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
63795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
63817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
63825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
63847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
63855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
63865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
63875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
63885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "https://www.another-origin.com/foo.dat"));
63895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
63915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
63925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
63935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 5, ASYNC),
63945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
63955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
63985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
63995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
64015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
64025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
64037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
64055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
64085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
64095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
64105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
64135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
64155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
64175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
64205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
64215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
64235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
64245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
64265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
64285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
64295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
64305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through an
64325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTPS proxy
64337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
64355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
64365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
64385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
64395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
64405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
64415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL from a server with a bad cert
64435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite bad_cert_writes[] = {
64445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
64455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
64465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
64475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead bad_cert_reads[] = {
64505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
64515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
64525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL with a good cert
64555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite good_data_writes[] = {
64565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
64575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
64585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
64595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
64605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
64615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
64625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead good_cert_reads[] = {
64655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
64665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
64675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
64685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
64695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
64705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
64735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_reads, arraysize(bad_cert_reads),
64745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_writes, arraysize(bad_cert_writes));
64755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
64765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                good_data_writes, arraysize(good_data_writes));
64775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
64785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
64795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
64845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then valid SSL certificate
6486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
64895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
64915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
64935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
64948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
64955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
64975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
65015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
65035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
65095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
65115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
65125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
65155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
65165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
65185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
65195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
65205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
65225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
65238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
65245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
65265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
65275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
65285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
65295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
65305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
65335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
65345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
65355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
65365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
65375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
65385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
65415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
65435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
65475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
65545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
65555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
65575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
65585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
65595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
65618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
65625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
65638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
65645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
65665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
65675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
65685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
65695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
65705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
65725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return an error, so the transaction stops here (this test isn't
65735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // interested in the rest).
65745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
65755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
65765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
65775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
65805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
65825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
65865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
65935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
65945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
65965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
65975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
65985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "http://the.previous.site.com/");
65995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
66015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
66028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
66035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
66055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
66065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
66075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
66085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Referer: http://the.previous.site.com/\r\n\r\n"),
66095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
66125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
66135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
66145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
66155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
66165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
66175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
66205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
66225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
66265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
66295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
66335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
66345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
66355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
66365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
66385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
66398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
66405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
66425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST / HTTP/1.1\r\n"
66435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
66445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
66455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
66465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
66495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
66505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
66515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
66525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
66535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
66545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
66575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
66595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
66635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
66665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
66705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
66715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "PUT";
66725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
66735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
66755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
66768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
66775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
66795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("PUT / HTTP/1.1\r\n"
66805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
66815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
66825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
66835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
66865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
66875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
66885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
66895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
66905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
66915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
66945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
66965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
67005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
67075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
67095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
67105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
67125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
67145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
67165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
67175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
67195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
67205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
67235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
67245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
67255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
67265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
67275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
67285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
67315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
67335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
67355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
67375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
67445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
67465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
67475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_BYPASS_CACHE;
67485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
67505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
67525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
67545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
67575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Pragma: no-cache\r\n"
67585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: no-cache\r\n\r\n"),
67595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
67625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
67635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
67645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
67655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
67665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
67675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
67705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
67725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
67745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
67765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
67835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       BuildRequest_CacheControlValidateCache) {
67845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
67865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
67875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_VALIDATE_CACHE;
67885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
67905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
67925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
67945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
67975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: max-age=0\r\n\r\n"),
67985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
68045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
68055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
68065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
68225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FooHeader", "Bar");
68265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
68305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
68355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FooHeader: Bar\r\n\r\n"),
68365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
68425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
68435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
68445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
68605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("referer", "www.foo.com");
68645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("hEllo", "Kitty");
68655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FoO", "bar");
68665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
68705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
68755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "referer: www.foo.com\r\n"
68765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "hEllo: Kitty\r\n"
68775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FoO: bar\r\n\r\n"),
68785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
68845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
68855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
68865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
69025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
69045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
69065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
69082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
69092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
69115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
69175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
69185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
69215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
69225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
69245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
69285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
69305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
69315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
69325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
69475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
69485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
69502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
69512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
69522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
69532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
69555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
69565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
69585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
69615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
69635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
69645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
69655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
69672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
69682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
69705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
69765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
69775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
69805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(write_buffer)),
69815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
69825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
69845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
69885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(read_buffer)),
69895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
69915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
69925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
69935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
70012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
70032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
70082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
70092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
70112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
70122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
70132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
70142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
70162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
70172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_text;
70192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
70202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
70212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("Payload", response_text);
70222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
70232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
70252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request;
70262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.method = "GET";
70272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.url = GURL("http://www.google.com/");
70282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.load_flags = 0;
70292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
70312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("socks4://myproxy:1080"));
70322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
70342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
70382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
70402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
70412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes[] = {
70432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
70442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
70462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
70472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
70482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
70502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
70512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
70532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Payload"),
70542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
70552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
70562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                data_writes, arraysize(data_writes));
7059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
70705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
70715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
70732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
70742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
70752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
70762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
70785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
70795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
70815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
70845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
70885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
70902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
70912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
70935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
70975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
70995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
71005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkRequest[] = {
71015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
71025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
71035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
71045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
71055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
71065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
71075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
71085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x50,  // 16-bit port (80)
71095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
71115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
71125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
71155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
71165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
71195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
71235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
71245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
71265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
71275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
71285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
71315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
71335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
71435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
71445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
71462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
71472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
71482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
71492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
71515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
71525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
71545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
71575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
71605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
71615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
71632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
71642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
71665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
71705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
71725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
71735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kSOCKS5OkRequest[] = {
71745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
71755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
71765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
71775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
71785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
71795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
71805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
71815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0xBB,  // 16-bit port (443)
71825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
71855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
71865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
71895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
71905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(kSOCKS5OkRequest)),
71915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
71945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
71985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
71995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
72005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
72015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
72025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
72035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
72065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
72115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
72135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
72185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
72215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
72225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
72242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
72252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
72262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
72272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
72295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
72305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
72325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
72355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that for connection endpoints the group names are correctly set.
72375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GroupNameTest {
72395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string proxy_server;
72405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
72415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_group_name;
72425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ssl;
72435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
72445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NextProto next_proto,
7247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps_) {
7248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
72495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
72515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
72525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
72535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair("host.with.alternate", 80), 443,
7254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(next_proto));
72555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session;
72575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GroupNameTransactionHelper(
72605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url,
72615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpNetworkSession>& session) {
72625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
72635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
72645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL(url);
72655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
72665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
72695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
72715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do not complete this request, the dtor will clean the transaction up.
72735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return trans->Start(&request, callback.callback(), BoundNetLog());
72745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
72775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
72795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
72805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
72815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
72825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/direct",
72835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
72845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
72855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
72865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
72875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
72885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://[2001:1418:13:1::25]/direct",
72895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[2001:1418:13:1::25]:80",
72905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
72915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
72925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
72945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
72955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
72965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/direct_ssl",
72975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
72985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
72995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
73005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
73015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
73025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://[2001:1418:13:1::25]/direct",
73035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/[2001:1418:13:1::25]:443",
73045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
73055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
73065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
73075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
73085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
73095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
73105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
73115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
73125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
73155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
73185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
73195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
73215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
73235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameTransportSocketPool* transport_conn_pool =
73245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameTransportSocketPool(NULL, NULL);
73255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
73265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
7327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
73295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
73305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
73335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
73355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
73365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
73375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
73385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
73395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
73405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
73415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                transport_conn_pool->last_group_name_received());
73425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
73435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
73475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
73485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
73495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
73505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/http_proxy_normal",
73515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
73525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
73535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
73545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
73565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
73575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
73585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/http_connect_ssl",
73595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
73605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
73615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
73625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
73645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
73655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
73665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
73675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
73685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
73692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
73712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http_proxy",
73722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp://ftp.google.com/http_proxy_normal",
73732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp/ftp.google.com:21",
73742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      false,
73752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    },
73765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
73795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
73825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
73835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
73855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
73875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("http_proxy", 80);
73895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
73905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
73915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
73925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
73935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
73965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
73975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
74005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
74025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
74035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
74045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
74055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
74065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
74075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
74085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                http_proxy_pool->last_group_name_received());
74095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
74105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
74115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
74135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
74145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
74155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
74165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks4_direct",
74175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/www.google.com:80",
74185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
74195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
74205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
74215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
74225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks5_direct",
74235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/www.google.com:80",
74245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
74255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
74265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
74285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
74295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
74305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks4_ssl",
74315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/www.google.com:443",
74325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
74335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
74345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
74355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
74365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks5_ssl",
74375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/ssl/www.google.com:443",
74385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
74395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
74405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
74425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
74435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
74445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/host.with.alternate:443",
74455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
74465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
74475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
74505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
74535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
74545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
74565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
74585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("socks_proxy", 1080);
74605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
74615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
74625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
74635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
74645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
74675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
74685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
74715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
7473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
74745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
74765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
74775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
74785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
74795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
74805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
74815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
74825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                socks_conn_pool->last_group_name_received());
74835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
74845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
74855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
74875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
74885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
74895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
74905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
74925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("myproxy:70;foobar:80"));
74935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This simulates failure resolving all hostnames; that means we will fail
74955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connecting to both proxies (myproxy:70 and foobar:80).
7496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
74975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
74995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
75008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
75015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
75035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
75055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
75065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
75085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
75095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base test to make sure that when the load flags for a request specify to
75125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bypass the cache, the DNS cache is not used.
75137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int load_flags) {
75155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a request, asking to bypass the cache(s).
75165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
75175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
75185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = load_flags;
75195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
75205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Select a host resolver that does caching.
7522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver);
75235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
75258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
75268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
75275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Warm up the host cache so it has an entry for "www.google.com".
75295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist;
75305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
7531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int rv = session_deps_.host_resolver->Resolve(
75323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
75333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
75343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
75353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
75363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
75373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
75385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
75395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
75405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
75415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that it was added to host cache, by doing a subsequent async lookup
75435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and confirming it completes synchronously.
7544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(
75453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
75463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
75473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
75483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
75493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
75503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
75515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, rv);
75525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject a failure the next time that "www.google.com" is resolved. This way
75545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can tell if the next lookup hit the cache, or the "network".
75555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (cache --> success, "network" --> failure).
7556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
75575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
75595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first read -- this won't be reached as the host resolution will fail first.
75605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
75615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
75635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the request.
75655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
75665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, rv);
75675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
75685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we bypassed the cache, we would have gotten a failure while resolving
75705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "www.google.com".
75715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
75725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are multiple load flags that should trigger the host cache bypass.
75755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test each in isolation:
75767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
75775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
75785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
75815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
75825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
75855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
75865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure we can handle an error when writing the request.
75897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
75905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
75915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
75925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
75935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
75945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure[] = {
75965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, ERR_CONNECTION_RESET),
75975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
75985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(NULL, 0,
75995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                write_failure, arraysize(write_failure));
7600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
76018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
76025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
76045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
76068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
76075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
76095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
76105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
76125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
76135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that a connection closed after the start of the headers finishes ok.
76167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
76175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
76185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
76195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
76205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
76215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
76235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1."),
76245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
76255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
76298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
76305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
76325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
76348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
76355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
76375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
76385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
76405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
76415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
76435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
76445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
76465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
76475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
76495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
76505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
76515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
76525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that a dropped connection while draining the body for auth
76555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// restart does the right thing.
76567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
76575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
76585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
76595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
76605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
76615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
76635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
76645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
76655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
76665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
76695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
76705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
76715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
76725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
76735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauth"),
76745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
76755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
76785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
7679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
76805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
76825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
76835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
76845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
76855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
76865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
76875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
76885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
76915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
76925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
76935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
76945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
76955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
76965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
76995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
7700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
77018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
77025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
77045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
77075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
77095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
77125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
77135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
77155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
77165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
77175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
77195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
77215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
77225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
77255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
77265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
77285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
77295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
77305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
77315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections going through a proxy that sends extra data.
77347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
7735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
77365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
77385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
77395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
77405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
77415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
77435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
77445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
77455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
77485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
77495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
7751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
77525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
77545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->ResetNextMockIndexes();
77565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
77585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
77598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
77605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
77625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
77655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
77665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
77695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
77705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
77715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
77725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
77735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
77755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
77768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
77775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
77795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
77805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
77815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
77855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
77875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
77895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
77925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
77945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
77955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
77975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
77985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
78005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
78015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
78025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
78052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file_path;
7806a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
78072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 kFakeSize = 100000;  // file is actually blank
78082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileElementReader::ScopedOverridingContentLengthForTests
78092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overriding_content_length(kFakeSize);
78102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
78122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
78137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
78147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file_path,
78157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
78167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
78177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
781868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
78192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
78225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
78232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
78245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
78255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
78295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
78315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
78325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
78335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
78345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
78395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
78415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
78475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
78485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
78505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
78515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
78535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
78545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
78565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file_path, false);
78585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
78612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file;
7862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
78632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string temp_file_content("Unreadable file.");
78642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
78652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   temp_file_content.length()));
78662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
78672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
78692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
78707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
78717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file,
78727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
78737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
78747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
787568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
78762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
78795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
78802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
78815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
78825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If we try to upload an unreadable file, the transaction should fail.
78848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
78875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7888f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StaticSocketDataProvider data(NULL, 0, NULL, 0);
7889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
78925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
78945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
7897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ERR_ACCESS_DENIED, rv);
78985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
7900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(response);
79015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file, false);
79035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
79064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class FakeUploadElementReader : public UploadElementReader {
79074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   public:
79084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FakeUploadElementReader() {}
79094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual ~FakeUploadElementReader() {}
79104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CompletionCallback& callback() const { return callback_; }
79124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // UploadElementReader overrides:
79144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Init(const CompletionCallback& callback) OVERRIDE {
79154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      callback_ = callback;
79164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_IO_PENDING;
79174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
79184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 GetContentLength() const OVERRIDE { return 0; }
79194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
79204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Read(IOBuffer* buf,
79214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     int buf_length,
79224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     const CompletionCallback& callback) OVERRIDE {
79234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_FAILED;
79244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
79254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   private:
79274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CompletionCallback callback_;
79284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
79294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
79314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
79324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  element_readers.push_back(fake_reader);
79334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
79344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
79364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "POST";
79374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
79384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
79394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = 0;
79404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
79438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
79444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data;
79464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
79474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback;
79494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
79504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
79524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Transaction is pending on request body initialization.
79544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(fake_reader->callback().is_null());
79554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Return Init()'s result after the transaction gets destroyed.
79574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  trans.reset();
79584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  fake_reader->callback().Run(OK);  // Should not crash.
79594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
79604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
79615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that changes to Auth realms are treated like auth rejections.
79627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
79635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
79675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First transaction will request a resource and receive a Basic challenge
79705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with realm="first_realm".
79715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
79725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
79735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
79745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
79755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
79765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
79785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
79795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
79805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
79815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), provide an Authentication header
79845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for first_realm. The server will reject and provide a challenge with
79855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // second_realm.
79865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
79875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
79885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
79895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
79905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmF6\r\n"
79915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
79925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
79945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
79955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
79965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
79975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This again fails, and goes back to first_realm. Make sure that the
80005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry is removed from cache.
80015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
80025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
80035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
80045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
80055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
80065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
80075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
80095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
80105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
80115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
80125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try one last time (with the correct password) and get the resource.
80155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes4[] = {
80165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
80175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
80185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
80195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmFy\r\n"
80205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
80215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads4[] = {
80235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
80245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html; charset=iso-8859-1\r\n"
80255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n"
80265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"
80275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
80285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
80315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
80325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
80335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
80345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
80355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
80365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
80375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes4, arraysize(data_writes4));
8038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
8039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
8040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
8041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
80425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
80445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
80485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the first request with Authorize headers. There should be a
80505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for first_realm waiting to be filled in after the
80515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
80525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
80535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
80555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
80565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
80575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AuthChallengeInfo* challenge = response->auth_challenge.get();
80595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
80605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
80615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
80625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
80635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
80645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the second request with an incorrect password. There should be a
80665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for second_realm waiting to be filled in after the
80675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
80685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
80695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
80705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBaz), callback2.callback());
80715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
80735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
80745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
80755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
80775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
80785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
80795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
80805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("second_realm", challenge->realm);
80815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
80825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the third request with another incorrect password. There should be
80845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a password prompt for first_realm waiting to be filled in. If the password
80855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prompt is not present, it indicates that the HttpAuthCacheEntry for
80865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first_realm was not correctly removed.
80875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
80885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
80895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kSecond, kFou), callback3.callback());
80905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
80925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
80935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
80945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
80965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
80975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
80985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
80995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
81005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
81015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the fourth request with the correct password and username.
81035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
81045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
81055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBar), callback4.callback());
81065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
81085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
81095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
81105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
81115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
81125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
81155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
81165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
81175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
81215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
81225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
81245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
81255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
81265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
81275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
81295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
81305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
81315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
81325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
81345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
81365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
81425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
81445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair http_host_port_pair("www.google.com", 80);
81475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpServerProperties& http_server_properties =
81485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *session->http_server_properties();
81495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
81505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.HasAlternateProtocol(http_host_port_pair));
81515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
81535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
81555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
81575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
81585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
81595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
81605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
81625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
81635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
81645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
81665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PortAlternateProtocolPair alternate =
81675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.GetAlternateProtocol(http_host_port_pair);
81685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PortAlternateProtocolPair expected_alternate;
81695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_alternate.port = 443;
8170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
81715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(expected_alternate.Equals(alternate));
81725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
81755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MarkBrokenAlternateProtocolAndFallback) {
81765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
81775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
81795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
81805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
81815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
81825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
81845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
81855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
81875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
81895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
81905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
81915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
81925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
81935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
81945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
81965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8199ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
82005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
82015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Port must be < 1024, or the header will be ignored (since initial port was
82025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // port 80 (another restricted port).
82035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
82045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
82055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      666 /* port is ignored by MockConnect anyway */,
8206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
82075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
82105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
82115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
82135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
82145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
82155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
82175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
82195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
82205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
82225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
82235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
82245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
82265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url)));
82275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PortAlternateProtocolPair alternate =
82285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties->GetAlternateProtocol(
82295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HostPortPair::FromURL(request.url));
82305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
82315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
82325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
82345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedBlocked) {
82355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
82365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
82375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
82385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
82395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
82405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
82425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
82435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
82445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
82455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
82475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
82485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
82505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
82525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
82535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
82545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
82555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
82575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
82595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
82615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
82635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
82645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
82655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
82665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
82675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
82695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
82725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
82735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
82752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
82762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
82775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
82785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid change to unrestricted port should fail.
82795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
82802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
82815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
82832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       AlternateProtocolPortRestrictedPermitted) {
82842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure that we're allowed to redirect traffic via an alternate
82852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
82862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a restricted port (port < 1024) if we set
82872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enable_user_alternate_protocol_ports.
82882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
8290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.enable_user_alternate_protocol_ports = true;
82912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo restricted_port_request;
82932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.method = "GET";
82942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
82952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.load_flags = 0;
82962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
82982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider first_data;
82992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first_data.set_connect_data(mock_connect);
8300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
83012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
83022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
83032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
83042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("hello world"),
83052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, OK),
83062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
83072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider second_data(
83082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
83102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
83122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8313ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
83142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session->http_server_properties();
83152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
83162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  http_server_properties->SetAlternateProtocol(
83172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
83182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kUnrestrictedAlternatePort,
8319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
83202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
83212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
83232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
83242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
83252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Start(
83262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
83272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog()));
83282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change to unrestricted port should succeed.
83292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
83305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
83315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
83335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedAllowed) {
83345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
83355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
83365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
83375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
83385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
83395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
83415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
83425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
83435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
83445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
83465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
83475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
83495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
83515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
83525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
83535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
83545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
83565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
83585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
83605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
83625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
83635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
83645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
83655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
83665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
83685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
83715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
83725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
83742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
83752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
83765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
83785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
83795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
83805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
83825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed1) {
83835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
83845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
83855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
83865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
83875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
83885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
83905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
83915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
83925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
83935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
83955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
83965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
83985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
84015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
84035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
84055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
84075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8410ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
84115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
84125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
84135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
84145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
84155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
84175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
84235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
84245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
84265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
84275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
84305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed2) {
84315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
84325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
84335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
84345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
84355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
84365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
84385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
84395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
84405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
84415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
84435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
84445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
84465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
84495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
84515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
84535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
84555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
84595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
84605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
84615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
84625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
84635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
84655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
84715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
84725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to an unrestricted port should pass.
84745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
84755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
84785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolUnsafeBlocked) {
84795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
84805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unsafe port, and that we resume the second
84815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
84825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
84835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
84855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
84865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
84875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
84885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The alternate protocol request will error out before we attempt to connect,
84905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so only the standard HTTP request will try to connect.
84915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
84935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
84955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(
84975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
84995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
85035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
85045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnsafePort = 7;
85055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
85065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
85075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnsafePort,
8508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
85095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
85135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
85155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The HTTP request should succeed.
85175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
85185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable alternate protocol before the asserts.
85205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(false);
85215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
85235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
85265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
85285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
85295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
85305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
85315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
85335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
85345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
85355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
85375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
85385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
85395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
85405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
85445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
85455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
85475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
85485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
85495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK)
85505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
85515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
85535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
85555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
85577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
85595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
856090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
856190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
85625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
85635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
85657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
85665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
85675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
85685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
85695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
85705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
85715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
85735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
85745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
85755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
85775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
85795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
85805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
85815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
85825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
85845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
85855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
85875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
85935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
85955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
85975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
86005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
86025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
86035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
86045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
86065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
86085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
86095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
86105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
86125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
86145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
86155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
86165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
86175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
86195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
86205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
86235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
86245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
86255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
86275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
86285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
86295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
86305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
86345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
86375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
86395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
86435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
86445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
86465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
86485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_socket(
86495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
86505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_socket.set_connect_data(never_finishing_connect);
86515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 2 and 3 are the hanging Alternate-Protocol and
86525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-Alternate-Protocol jobs from the 2nd transaction.
8653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
86555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
86577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
86595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
866090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
866190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
866290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
866390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
86645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
86655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1),
86665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
86675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
86697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
86707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
86717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
86725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
86735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1),
86745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data1),
86755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2),
86765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data2),
86775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
86785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
86815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2,  // wait for writes to finish before reading.
86825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
86835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
86845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 4 is the successful Alternate-Protocol for transaction 3.
8685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
86865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
86895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
86915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
8692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
86935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
86955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
86965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
86975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
86995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
87015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
87025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
87045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
87055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
87065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
8708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
87095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
87105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
8713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
87145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
87155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
87185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
87195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
87215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
87235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
87245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
87255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
87265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
87275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
87285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans3.GetResponseInfo();
87305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
87325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
87335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
87345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
87355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
87365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
87375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
87405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
87415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
87425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
87445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
87455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
87465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
87475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
87515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
87545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
87565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
87605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
87625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
87647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
87665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
87685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_alternate_protocol_socket(
87695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
87705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_alternate_protocol_socket.set_connect_data(
87715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
87735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_alternate_protocol_socket);
87745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2nd request is just a copy of the first one, over HTTP again.
8776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
87775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
87855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
87895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
87915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
87925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
87945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
87955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
87965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
88005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
88045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8805868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
88085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
88095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
88125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
88135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CapturingProxyResolver : public ProxyResolver {
88155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
88165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
88175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CapturingProxyResolver() {}
88185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetProxyForURL(const GURL& url,
88205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ProxyInfo* results,
88215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const CompletionCallback& callback,
88225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RequestHandle* request,
88232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const BoundNetLog& net_log) OVERRIDE {
88245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
88255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HostPortPair("myproxy", 80));
88265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->UseProxyServer(proxy_server);
88275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resolved_.push_back(url);
88285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
88295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
88305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelRequest(RequestHandle request) OVERRIDE {
88325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
88335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
88345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
88365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
88375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
88385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
88395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelSetPacScript() OVERRIDE {
88415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
88425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
88435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
88452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const CompletionCallback& /*callback*/) OVERRIDE {
88465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
88475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
88485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<GURL>& resolved() const { return resolved_; }
88505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
88525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> resolved_;
88535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
88555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
88565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
88585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForTunneledNpnSpdy) {
88595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
88605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
88615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
88635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_auto_detect(true);
88645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_pac_url(GURL("http://fooproxyurl"));
88655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
88675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
8868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
88695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
88705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
88712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
8872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
88735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
88755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
88765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
88775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
88785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
88825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
88835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
88855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
88865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
88875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
88885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
88915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
88935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
88957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
88975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
889890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
889990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
89005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
89015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
89025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
89035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
890490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*req),                              // 3
89055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
89085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
89107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
89115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
89125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
89135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 4),  // 2, 4
89145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 4),  // 5
89155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 4),  // 6
89165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
89195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
89205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
89225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
89245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
89255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
89265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
89275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
89295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
89305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
89325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
89342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
89365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
89385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
89405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
89425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
89445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
89465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
89475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
89495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
89505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
89515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
89535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
89555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
89575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
89595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
89615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
89635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
89645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
89665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
89675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
89685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://www.google.com/",
89695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[0].spec());
89705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https://www.google.com/",
89715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[1].spec());
89725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
89742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
89752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
89762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
89775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
89785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
89805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
89815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
89825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
89835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
89855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
89865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
89875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
89885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
89925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
89935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
89955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
89965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
89975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
90005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
90025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
90047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
90065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
900790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
900890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
90095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
90105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
90127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
90135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
90145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
90155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
90165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
90175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
90185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
90205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
90215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
90225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
90245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
90265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
90285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
90335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
90375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9038868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
90425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
90445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
90465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
904790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
904890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     kPrivacyModeDisabled);
9049ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
90507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateSecureSpdySession(session, key, BoundNetLog());
90515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
90555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
90595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9060868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
90635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
90645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
90675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
90685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GenerateAuthToken is a mighty big test.
90705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It tests all permutation of GenerateAuthToken behavior:
90715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Synchronous and Asynchronous completion.
90725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - OK or error on completion.
90735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Direct connection, non-authenticating proxy, and authenticating proxy.
90745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - HTTP or HTTPS backend (to include proxy tunneling).
90755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Non-authenticating and authenticating backend.
90765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
90775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In all, there are 44 reasonable permuations (for example, if there are
90785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// problems generating an auth token for an authenticating proxy, we don't
90795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to test all permutations of the backend server).
90805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
90815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test proceeds by going over each of the configuration cases, and
90825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// potentially running up to three rounds in each of the tests. The TestConfig
90835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifies both the configuration for the test as well as the expectations
90845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the results.
90857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
90865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kServer[] = "http://www.example.com";
90875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kSecureServer[] = "https://www.example.com";
90885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kProxy[] = "myproxy:70";
90895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
90905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum AuthTiming {
90925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_NONE,
90935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_SYNC,
90945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_ASYNC,
90955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
90965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
90985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
90995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
91015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxy(
91025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
91035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
91055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
91065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
91075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
91095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
91105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxyAuth(
91115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
91125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
91145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
91155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthThroughProxy(
91165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
91175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
91195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
91205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthWithProxyAuth(
91215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
91225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
91245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n"
91255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
91265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnect(
91275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
91285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
91305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnectProxyAuth(
91315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
91325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
91335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
91345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
91355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
91375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
91385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
91395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
91405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
91415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kFailure(
91425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Should not be called.");
91435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
91445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
91455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
91465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
91475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
91485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
91495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyChallenge(
91505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 407 Unauthorized\r\n"
91515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authenticate: Mock realm=proxy\r\n"
91525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: close\r\n"
91535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
91545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
91555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
91565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyConnected(
91575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 Connection Established\r\n\r\n");
91585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
91605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no constructors, but the C++ compiler on Windows warns about
91615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unspecified data in compound literals. So, moved to using constructors,
91625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and TestRound's created with the default constructor should not be used.
91635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestRound {
91645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound()
91655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : expected_rv(ERR_UNEXPECTED),
91665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
91675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
91685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
91695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
91705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg)
91715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
91725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
91735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
91745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
91755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
91765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
91775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
91785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg, const MockWrite* extra_write_arg,
91795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const MockRead* extra_read_arg)
91805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
91815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
91825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
91835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(extra_write_arg),
91845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(extra_read_arg) {
91855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
91865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite write;
91875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead read;
91885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_rv;
91895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* extra_write;
91905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* extra_read;
91915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNoSSL = 500;
91945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestConfig {
91965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* proxy_url;
91975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming proxy_auth_timing;
91985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int proxy_auth_rv;
91995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* server_url;
92005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming server_auth_timing;
92015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int server_auth_rv;
92025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_auth_rounds;
92035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int first_ssl_round;
92045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound rounds[3];
92055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } test_configs[] = {
92065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server with a direct connection.
92075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
92085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
92095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server with a direct connection.
92105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
92115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
92135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
92145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
92165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
92175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
92195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
92205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
92225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through a non-authenticating proxy.
92235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
92245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kSuccess, OK)}},
92255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through a non-authenticating proxy.
92265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
92275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
92285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
92295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
92305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
92315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
92325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
92335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
92345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
92355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
92365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
92375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
92385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through an authenticating proxy.
92395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
92405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
92425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
92435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
92455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
92465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
92485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
92495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
92515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through an authenticating proxy.
92525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
92535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
92565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
92575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
92605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
92615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
92645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
92655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
92685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
92695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
92725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
92735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
92765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
92775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
92805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
92815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
92825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
92835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
92845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a direct connection.
92855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
92865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
92875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server with a direct connection.
92885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
92895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
92915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
92925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
92945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
92955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
92975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
92985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
92995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
93005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a non-authenticating proxy.
93015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
93025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
93035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through a non-authenticating proxy.
93045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
93055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
93065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
93075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
93085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
93095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
93105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
93115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
93125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
93135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
93145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
93155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
93165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-Authenticating HTTPS server through an authenticating proxy.
93175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
93185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
93205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
93215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
93235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
93245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
93265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
93275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
93295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through an authenticating proxy.
93305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
93315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
93355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
93365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
93405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
93415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
93455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
93465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
93505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
93515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
93555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
93565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
93605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
93615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
93655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
93665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
93675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
93685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
93695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
93705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
93735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpAuthHandlerMock::Factory* auth_factory(
93745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new HttpAuthHandlerMock::Factory());
9375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.http_auth_handler_factory.reset(auth_factory);
93765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TestConfig& test_config = test_configs[i];
93775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up authentication handlers as necessary.
93795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_auth_timing != AUTH_NONE) {
93805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int n = 0; n < 2; n++) {
93815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
93825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string auth_challenge = "Mock realm=proxy";
93835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL origin(test_config.proxy_url);
93845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
93855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               auth_challenge.end());
93865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
93875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        origin, BoundNetLog());
93885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->SetGenerateExpectation(
93895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_timing == AUTH_ASYNC,
93905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_rv);
93915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
93925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
93935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
93945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.server_auth_timing != AUTH_NONE) {
93955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
93965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string auth_challenge = "Mock realm=server";
93975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL origin(test_config.server_url);
93985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
93995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             auth_challenge.end());
94005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
94015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      origin, BoundNetLog());
94025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->SetGenerateExpectation(
94035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_timing == AUTH_ASYNC,
94045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_rv);
94055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
94065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_url) {
9408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(
94095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ProxyService::CreateFixed(test_config.proxy_url));
94105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(ProxyService::CreateDirect());
94125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
94155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
94165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL(test_config.server_url);
94175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
94185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
94208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
94215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int round = 0; round < test_config.num_auth_rounds; ++round) {
94235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TestRound& read_write_round = test_config.rounds[round];
94245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Set up expected reads and writes.
94265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead reads[2];
94275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reads[0] = read_write_round.read;
94285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_reads = 1;
94295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_read) {
94305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reads[1] = *read_write_round.extra_read;
94315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_reads = 2;
94325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
94335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite writes[2];
94355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes[0] = read_write_round.write;
94365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_writes = 1;
94375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_write) {
94385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        writes[1] = *read_write_round.extra_write;
94395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_writes = 2;
94405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
94415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StaticSocketDataProvider data_provider(
94425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reads, length_reads, writes, length_writes);
9443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
94445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add an SSL sequence if necessary.
94465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
94475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round >= test_config.first_ssl_round)
9448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_deps_.socket_factory->AddSSLSocketDataProvider(
94495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &ssl_socket_data_provider);
94505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Start or restart the transaction.
94525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestCompletionCallback callback;
94535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int rv;
94545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round == 0) {
94555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.Start(&request, callback.callback(), BoundNetLog());
94565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
94575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.RestartWithAuth(
94585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AuthCredentials(kFoo, kBar), callback.callback());
94595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
94605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rv == ERR_IO_PENDING)
94615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = callback.WaitForResult();
94625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Compare results with expected data.
94645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(read_write_round.expected_rv, rv);
94655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpResponseInfo* response = trans.GetResponseInfo();
94665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.expected_rv == OK) {
94675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ASSERT_TRUE(response != NULL);
94685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
94695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response == NULL);
94705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(round + 1, test_config.num_auth_rounds);
94715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
94725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
94735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round + 1 < test_config.num_auth_rounds) {
94745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(response->auth_challenge.get() == NULL);
94755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
94765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response->auth_challenge.get() == NULL);
94775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
94785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
94805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
94815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
94835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do multi-round authentication and make sure it works correctly.
94845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock::Factory* auth_factory(
94855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerMock::Factory());
9486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(auth_factory);
9487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
94905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
94925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->set_connection_based(true);
94935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string auth_challenge = "Mock realm=server";
94945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin("http://www.example.com");
94955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
94965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         auth_challenge.end());
94975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
94985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  origin, BoundNetLog());
94995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
95005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = OK;
95025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = NULL;
95035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
95045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
95055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = origin;
95065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
95075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
95095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use a TCP Socket Pool with only one connection per group. This is used
95115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to validate that the TCP socket is not released to the pool between
95125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // each round of multi-round authentication.
95135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSessionPeer session_peer(session);
95145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
95155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
95165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,  // Max sockets for pool
95175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,   // Max sockets per group
95185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &transport_pool_histograms,
9519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.host_resolver.get(),
9520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory.get(),
9521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.net_log);
9522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new MockClientSocketPoolManager);
95245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_pool_manager->SetTransportSocketPool(transport_pool);
9525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  session_peer.SetClientSocketPoolManager(
9526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      mock_pool_manager.PassAs<ClientSocketPoolManager>());
95275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
95305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
95315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
95335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
95345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
95355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
95365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
95375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
95385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
95395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
95405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
95415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
95435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
95445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
95455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
95465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
95475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
95485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
95495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
95505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
95515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
95525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
95535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
95555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
95565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
95575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
95585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
95595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
95605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
95615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
95625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
95635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing request
95645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
95655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
95665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
95675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
95685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
95695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
95705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
95715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
95725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
95735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
95745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
95755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing response
95765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
95775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
95785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_provider(reads, arraysize(reads),
95795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         writes, arraysize(writes));
9580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
95815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kSocketGroup = "www.example.com:80";
95835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round of authentication.
95855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
95865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
95875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
95885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
95895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
95905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
95915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
95925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->auth_challenge.get() == NULL);
95935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
95945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In between rounds, another request comes in for the same domain.
95965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should not be able to grab the TCP socket that trans has already
95975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // claimed.
95985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans_compete(
9599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
96005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_compete;
96015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_compete->Start(
96025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &request, callback_compete.callback(), BoundNetLog());
96035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
96045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback_compete.WaitForResult at this point would stall forever,
96055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since the HttpNetworkTransaction does not release the request back to
96065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool until after authentication completes.
96075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round of authentication.
96095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
96105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
96115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
96125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
96135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
96145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
96155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
96165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
96175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
96185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Third round of authentication.
96205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
96215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
96225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
96235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
96245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
96255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
96265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
96275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
96285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
96295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fourth round of authentication, which completes successfully.
96315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
96325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
96335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
96345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
96355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
96365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
96375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
96385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
96395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
96405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the body since the fourth round was successful. This will also
96425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // release the socket back to the pool.
96435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
96455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
96465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
96475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
96495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
96505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are still 0 idle sockets, since the trans_compete transaction
96515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be handed it immediately after trans releases it to the group.
96525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
96535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The competing request can now finish. Wait for the headers and then
96555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read the body.
96565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_compete.WaitForResult();
96575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
96595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
96605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
96615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
96635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
96645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, the socket is released to the group.
96665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
96675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
96685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests the case that a request is issued via http instead of spdy after
96705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// npn is negotiated.
96717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
96725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
9673ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::vector<NextProto> next_protos;
9674ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  next_protos.push_back(kProtoHTTP11);
9675ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  HttpStreamFactory::SetNextProtos(next_protos);
96765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
96775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
96785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
96795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
96805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
96825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
96835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
96845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
96855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
96905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
96915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
96935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
96945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
96955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
96985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
96995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto = "http/1.1";
97005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.protocol_negotiated = kProtoHTTP11;
97015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
97035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
97055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
9706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
97075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
97095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
97135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
97155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
97175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
97185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
97205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
97225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
97235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
97255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
97265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
97275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
97295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
97305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
97315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
97335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the SSL handshake completing with an NPN negotiation
97345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // followed by an immediate server closing of the socket.
97355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fix crash:  http://crbug.com/46369
97365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
97375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
97385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
97405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
97415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
97425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
97435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
97457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
97475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
974890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
974990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
97505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
97515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
97535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
97545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
97555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
97575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,  // don't wait in this case, immediate hangup.
97585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
97595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
97615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
97635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
97675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
97695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
97705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
97715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
97725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9773ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A subclass of HttpAuthHandlerMock that records the request URL when
9774ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// it gets it. This is needed since the auth handler may get destroyed
9775ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// before we get a chance to query it.
9776ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9777ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public:
9778ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9779ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
9780ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual ~UrlRecordingHttpAuthHandlerMock() {}
9781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
9782ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch protected:
9783ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9784ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const HttpRequestInfo* request,
9785ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const CompletionCallback& callback,
9786ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    std::string* auth_token) OVERRIDE {
9787ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *url_ = request->url;
9788ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        credentials, request, callback, auth_token);
9790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
9791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
9792ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private:
9793ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL* url_;
9794ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
9795ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
97967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
97975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test ensures that the URL passed into the proxy is upgraded
97985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to https when doing an Alternate Protocol upgrade.
97995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
9800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
98015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
98032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
98042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
9805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
9806ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL request_url;
9807ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
9808ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    HttpAuthHandlerMock::Factory* auth_factory =
9809ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new HttpAuthHandlerMock::Factory();
9810ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UrlRecordingHttpAuthHandlerMock* auth_handler =
9811ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new UrlRecordingHttpAuthHandlerMock(&request_url);
9812ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9813ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->set_do_init_from_challenge(true);
9814ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    session_deps_.http_auth_handler_factory.reset(auth_factory);
9815ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
98165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
98185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
98195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com");
98205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
98215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round goes unauthenticated through the proxy.
98235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_1[] = {
98245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
98255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
98265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
98275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
98285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_1[] = {
98305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
98315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
98325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Alternate-Protocol: 443:npn-spdy/2\r\n"
98335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Proxy-Connection: close\r\n"
98345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
98355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
98375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  data_writes_1, arraysize(data_writes_1));
98385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round tries to tunnel to www.google.com due to the
98405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Alternate-Protocol announcement in the first round. It fails due
98415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a proxy authentication challenge.
98425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the failure, a tunnel is established to www.google.com using
98435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Proxy-Authorization headers. There is then a SPDY request round.
98445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
98455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Despite the "Proxy-Connection: Close", these are done on the
98465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
98475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // does a Disconnect and Connect on the same socket, rather than trying
98485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to obtain a new one.
98495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
98505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Originally, the proxy response to the second CONNECT request
98515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simply returned another 407 so the unit test could skip the SSL connection
98525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // establishment and SPDY framing issues. Alas, the
98535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // retry-http-when-alternate-protocol fails logic kicks in, which was more
98545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complicated to set up expectations for than the SPDY session.
98555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
985790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
98587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
98597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
98605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_2[] = {
98625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt without Proxy-Authorization.
98635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
98645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
98655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
98665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
98675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt with Proxy-Authorization.
98695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
98705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
98715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
98725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: auth_token\r\n"
98735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
98745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY request
98765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
98775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
98795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Authenticate: Mock\r\n"
98805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Connection: close\r\n"
98815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "\r\n");
98825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
98835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_2[] = {
98845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt fails
98855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
98865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kRejectConnectResponse,
98875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kRejectConnectResponse) - 1, 1),
98885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt passes
98905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kAcceptConnectResponse,
98915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kAcceptConnectResponse) -1, 4),
98925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY response
98945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 6),
98955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 6),
98965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 6),
98975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_2(
98995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads_2, arraysize(data_reads_2),
99005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes_2, arraysize(data_writes_2));
99015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
99037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
99045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
99065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
99075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
99085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
99095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
99105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
99155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
9916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
99175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round should work and provide the Alternate-Protocol state.
99195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_1;
99202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_1(
9921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
99225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
99235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
99245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_1.WaitForResult());
99255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round should attempt a tunnel connect and get an auth challenge.
99275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_2;
99282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_2(
9929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
99305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
99315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
99325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_2.WaitForResult());
99335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans_2->GetResponseInfo();
99345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
99355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response->auth_challenge.get() == NULL);
99365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart with auth. Tunnel should work and response received.
99385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_3;
99395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->RestartWithAuth(
99405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback_3.callback());
99415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
99425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_3.WaitForResult());
99435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After all that work, these two lines (or actually, just the scheme) are
99455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // what this test is all about. Make sure it happens correctly.
99465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https", request_url.scheme());
99475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com", request_url.host());
99485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
99502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
99512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
99522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
99535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we cancel the transaction as the connection is completing, that
99565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything tears down correctly.
99577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
99585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup everything about the connection to complete synchronously, so that
99595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after calling HttpNetworkTransaction::Start, the only thing we're waiting
99605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for is the callback from the HttpStreamRequest.
99615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then cancel the transaction.
99625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that we don't crash.
99635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(SYNCHRONOUS, OK);
99645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
99655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
99665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello world"),
99675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
99685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
99715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
99725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
99735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
99745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
99768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
99775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
99788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
99795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
99815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.set_connect_data(mock_connect);
9982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
99835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
99855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
99875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
99885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
99895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();  // Cancel the transaction here.
99905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
999190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
99925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic GET request through a proxy.
99957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyGet) {
9996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
99972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
99985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
9999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
100015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
100035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
100045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
100055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
100075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
100085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
100095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
100105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
100135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
100145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
100155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
100165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
100175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
100205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
100225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
100245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
100275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
100295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
100325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
100335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
100355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
100365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
100385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
100395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
100405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
100415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
100422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
100432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
100442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
100452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
100462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
100475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy.
100507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
100522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
100535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
100565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
100585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
100595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
100605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
100625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
100635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
100645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
100655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
100665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
100685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
100695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
100705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
100735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
100745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
100765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
100775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
100785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
100795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
100825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
100845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
100865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
100885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
100915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
100935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
100965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
100975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
100985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
100995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
101005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
101015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
101025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
101035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
101045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
101055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
101065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
101085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
101095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
101115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
101125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
101135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
101145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
101152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
101162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
101172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
101182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
101192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
101205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
101215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy, but the server hangs up
101235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while establishing the tunnel.
101247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
101265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
101295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
101315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
101325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
101335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
101355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
101365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
101375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
101395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
101415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
101435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
101465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
101475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
101485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
101495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
101525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
101545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
101565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
101585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
101615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
101635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
101645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
101665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
101675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
101685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
101695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
101705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
101715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
101725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
101735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
101745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
101755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
101765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
101775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for crbug.com/55424.
101797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
1018090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1018190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
101825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
101835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
101857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
101865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
101875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
101885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
101895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
101905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
101935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
101945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
101955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
101975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
101997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
102015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
102055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
1020690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
1020790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     kPrivacyModeDisabled);
10208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
102097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateInsecureSpdySession(session, key, BoundNetLog());
102105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
102125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
102135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
102145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
102155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the important line that marks this as a preconnect.
102175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
102185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestCompletionCallback callback;
102235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
102245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
102265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given a net error, cause that error to be returned from the first Write()
102295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call and verify that the HttpTransaction fails with that error.
102307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int error, IoMode mode) {
102325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
102335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
102345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
102355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
102365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data(mode, OK);
102385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockWrite data_writes[] = {
102395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockWrite(mode, error),
102405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
102415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data(NULL, 0,
102425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     data_writes, arraysize(data_writes));
10243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
102455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
102515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
102525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == net::ERR_IO_PENDING)
102535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
102545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(error, rv);
102555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
102585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just check a grab bag of cert errors.
102595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kErrors[] = {
102605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_COMMON_NAME_INVALID,
102615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_AUTHORITY_INVALID,
102625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_DATE_INVALID,
102635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
102645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kErrors); i++) {
102655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], ASYNC);
102665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
102675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
102685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
102715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
102725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
102735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is disabled.
102745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
102755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
102767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
102775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_NoFalseStart) {
102785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
102795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
102805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
102815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
102825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
102845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
102855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 contains the data for the first SSL handshake. When a
102875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CertificateRequest is received for the first time, the handshake will
102885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be aborted to allow the caller to provide a certificate.
102895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
102905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
102925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
102945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data2 contains the data for the second SSL handshake. When TLS
102965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // False Start is not being used, the result of the SSL handshake will be
102975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned as part of the SSLClientSocket::Connect() call. This test
102985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // matches the result of a server sending a handshake_failure alert,
102995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // rather than a Finished message, because it requires a client
103005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate and none was supplied.
103015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
103025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
103045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
103065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data3 contains the data for the third SSL handshake. When a
103085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
103095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
103105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1.1. This is transparent to the caller
103115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
103125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
103135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
103145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
103155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
103175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
103195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 contains the data for the fourth SSL handshake. When a
103215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
103225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
103235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1. This is transparent to the caller
103245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
103255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
103265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
103275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
103285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
103305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
103325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
103412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
103435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the SSL handshake with the peer. This consumes ssl_data1.
103455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
103465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
103475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
103485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
103505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
103515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
103525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
103535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
103555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
103565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
103575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
103585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
103595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
103605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
103625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
103635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
103645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
103655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
103665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
103675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
103695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
103705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
103715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
103725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
103735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
103755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
103765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
103775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
103785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
103795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
103815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
103825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
103835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is enabled.
103845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
103855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
103867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
103875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_FalseStart) {
103885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
103895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
103905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
103915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
103925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
103945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
103955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When TLS False Start is used, SSLClientSocket::Connect() calls will
103975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return successfully after reading up to the peer's Certificate message.
103985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is to allow the caller to call SSLClientSocket::Write(), which can
103995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enqueue application data to be sent in the same packet as the
104005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChangeCipherSpec and Finished messages.
104015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual handshake will be finished when SSLClientSocket::Read() is
104025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which expects to process the peer's ChangeCipherSpec and
104035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finished messages. If there was an error negotiating with the peer,
104045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // such as due to the peer requiring a client certificate when none was
104055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied, the alert sent by the peer won't be processed until Read() is
104065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called.
104075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Like the non-False Start case, when a client certificate is requested by
104095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the peer, the handshake is aborted during the Connect() call.
104105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 represents the initial SSL handshake with the peer.
104115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
104125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
104145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
104165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When a client certificate is supplied, Connect() will not be aborted
104185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the peer requests the certificate. Instead, the handshake will
104195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // artificially succeed, allowing the caller to write the HTTP request to
104205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the socket. The handshake messages are not processed until Read() is
104215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which then detects that the handshake was aborted, due to the
104225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // peer sending a handshake_failure because it requires a client
104235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate.
104245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
104255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
104275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockRead data2_reads[] = {
104285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
104295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(
104315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
104335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
104355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the data for the SSL handshake once the TLSv1.1 connection falls back to
104365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TLSv1. It has the same behaviour as [ssl_]data2.
104375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
104385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
104405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(
104415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
104435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
104455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
104465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
104475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
104495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(
104505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
104525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(
10458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
104622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
104645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the initial SSL handshake.
104665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
104675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
104685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
104695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
104715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
104725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
104735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
104745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
104765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
104775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
104785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
104795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
104805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
104815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
104835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
104845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
104855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
104865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
104875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
104885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
104905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
104915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
104925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
104935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
104945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
104965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
104975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
104985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
104995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
105025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
105035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) An HTTPS proxy is involved.
105045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The HTTPS proxy requests a client certificate.
105055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate for the
105065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     proxy.
105075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test is repeated twice, first for connecting to an HTTPS endpoint,
105085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then for connecting to an HTTP endpoint.
105097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
105115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
105125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
105145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
105165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("proxy", 70);
105175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
105195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data[1-3]. Rather than represending the endpoint
105205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (www.example.com:443), they represent failures with the HTTPS proxy
105215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (proxy:70).
105225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
105235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
105255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
105275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
105295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
105315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
105335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
105355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
105365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
105375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
105395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
105415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
105425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo requests[2];
105445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].url = GURL("https://www.example.com/");
105455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].method = "GET";
105465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].load_flags = net::LOAD_NORMAL;
105475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].url = GURL("http://www.example.com/");
105495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].method = "GET";
105505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].load_flags = net::LOAD_NORMAL;
105515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(requests); ++i) {
10553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
10554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans(
10556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Begin the SSL handshake with the proxy.
105595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
105605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(
105615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &requests[i], callback.callback(), net::BoundNetLog());
105625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
105635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Complete the SSL handshake, which should abort due to requiring a
105655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // client certificate.
105665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
105675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
105685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicate that no certificate should be supplied. From the perspective
105705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of SSLClientCertCache, NULL is just as meaningful as a real
105715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate, so this is the same as supply a
105725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // legitimate-but-unacceptable certificate.
105735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithCertificate(NULL, callback.callback());
105745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
105755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was added to the client auth cache before
105775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // allowing the connection to continue restarting.
105785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<X509Certificate> client_cert;
105795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
105805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
105815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(NULL, client_cert.get());
105825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was NOT cached for the endpoint. This only
105835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // applies to HTTPS requests, but is fine to check for HTTP requests.
105845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
105855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
105865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart the handshake. This will consume ssl_data2, which fails, and
105885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then consume ssl_data3, which should also fail. The result code is
105895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // checked against what ssl_data3 should return.
105905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
105915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
105925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now that the new handshake has failed, ensure that the client
105945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate was removed from the client auth cache.
105955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
105965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
105975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
105985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
105995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
106015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Unlike TEST/TEST_F, which are macros that expand to further macros,
106037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TEST_P is a macro that expands directly to code that stringizes the
106047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// arguments. As a result, macros passed as parameters (such as prefix
106057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// or test_case_name) will not be expanded by the preprocessor. To
106067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// work around this, indirect the macro for TEST_P, so that the
106077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// pre-processor will expand macros such as MAYBE_test_name before
106087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// instantiating the test.
106097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define WRAPPED_TEST_P(test_case_name, test_name) \
106107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TEST_P(test_case_name, test_name)
106117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
106125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
106135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
106145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
106155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
106165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
106175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
106187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
106195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
106205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
106215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
10624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
106255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
106265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
106275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
106297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
106315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1063290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1063390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1063490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1063590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
106365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
106375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
106385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
106395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
106407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
106417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
106427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
106437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
106447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
106457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
106467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
106477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
106485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
106495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
106505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
106515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
106525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
106535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
106545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
106555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
106575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
106585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
106595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
106605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
106615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
106625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
106635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
106655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
106675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
106685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
106695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
106705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
106725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
106745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
106755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
106765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
106785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
106805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
106815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
106835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
106845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
106855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload www.gmail.com into HostCache.
106875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port("www.gmail.com", 443);
106885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(host_port);
106895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
106903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(resolve_info,
106913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            DEFAULT_PRIORITY,
106923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            &ignored,
106933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            callback.callback(),
106943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            NULL,
106953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            BoundNetLog());
106965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
106975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
106985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
106995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
107015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
107025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
107035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
107055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
107075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
107085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
107095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
107115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
107135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
107145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
107155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
107165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
107175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
107185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
107195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPooling
107205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
107225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
107235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
107245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
10727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
107285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
107295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
107305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
107327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
107345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1073590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1073690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1073790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1073890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
107395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
107405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
107415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
107425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
107447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
107457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
107467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
107477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
107487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
107497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
107507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
107515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
107525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
107535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
107545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
107555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
107565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
107575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
107605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
107615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
107625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
107635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
107645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
107655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
107665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
107685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
107705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
107715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
107725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
107735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
107755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
107775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
107785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
107795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
107815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
107835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
107845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
107865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
107875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
107885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
107905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
107915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
107925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
107945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
107965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
107975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
107985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
108005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
108025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
108035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
108045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
108055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
108065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
108075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
108085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OneTimeCachingHostResolver : public net::HostResolver {
108105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
108115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
108125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : host_port_(host_port) {}
108135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OneTimeCachingHostResolver() {}
108145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
108165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HostResolver methods:
108185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Resolve(const RequestInfo& info,
108193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      RequestPriority priority,
108205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      AddressList* addresses,
108215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const CompletionCallback& callback,
108225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      RequestHandle* out_req,
108235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const BoundNetLog& net_log) OVERRIDE {
108245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return host_resolver_.Resolve(
108253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        info, priority, addresses, callback, out_req, net_log);
108265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
108275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int ResolveFromCache(const RequestInfo& info,
108295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               AddressList* addresses,
108305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const BoundNetLog& net_log) OVERRIDE {
108315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
108325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == OK && info.host_port_pair().Equals(host_port_))
108335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_.GetHostCache()->clear();
108345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
108355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
108365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(RequestHandle req) OVERRIDE {
108385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_resolver_.CancelRequest(req);
108395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
108405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver* GetMockHostResolver() {
108425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &host_resolver_;
108435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
108445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
108465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver host_resolver_;
108475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HostPortPair host_port_;
108485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
108495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
108515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
10852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
108545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
10855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UseIPConnectionPoolingWithHostCacheExpiration
108575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
108587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest,
108597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
108607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
108617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// prefix doesn't work with parametrized tests).
108627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
108637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return;
108647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
108657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
108665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
108675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
108685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
108705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
108712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpNetworkSession::Params params =
10872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::CreateSessionParams(&session_deps_);
108735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.host_resolver = &host_resolver;
10874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
108755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
108765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
108775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
108797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
108815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1088290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1088390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1088490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1088590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
108865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
108875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
108885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
108895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
108907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
108917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
108927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
108937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
108947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
108957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
108967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
108977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
108985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
108995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
109005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
109015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
109025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
109035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
109045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
109075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
109085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
109095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
109105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
109115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
109125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
109135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
109155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
109175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
109185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
109195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
109205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
109225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
109245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
109255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
109265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
109285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
109305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
109315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
109335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
109345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
109355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload cache entries into HostCache.
109375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
109385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
109393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = host_resolver.Resolve(resolve_info,
109403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             DEFAULT_PRIORITY,
109413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             &ignored,
109423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             callback.callback(),
109433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             NULL,
109443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             BoundNetLog());
109455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
109465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
109475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
109485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
109505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
109515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
109525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
109545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
109565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
109575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
109585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
109605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
109625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
109635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
109645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
109655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
109665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
109675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
109685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
109695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
109715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
109725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
109735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
109755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
109765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
109775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
109785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
109805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
109815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider* data[] = { &data1, &data2 };
109825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
109845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
109865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
109875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
109885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
109895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
109915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
109925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
109935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
109955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
109965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
109975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
109985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
110005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
110015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
110025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
110035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(NULL, 0,
110055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
110065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
110075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
110085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider* data[] = { &data1, &data2 };
110095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
110115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
110135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
110145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
110155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
110165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
110185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
110195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
110205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1102290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1102390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
110245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
110265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
110275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
110307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
110315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
110325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
110335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
110345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 3)
110355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data1(
110385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads1, arraysize(reads1),
110395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes1, arraysize(writes1));
110405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
110415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
110425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP GET for the HTTP URL
110445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
110455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 4,
110465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "GET / HTTP/1.1\r\n"
110475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com:443\r\n"
110485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
110495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
110525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
110535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 6, "hello"),
110545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 7, OK),
110555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data2(
110585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads2, arraysize(reads2),
110595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes2, arraysize(writes2));
110605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
110627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
11065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
110665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
110685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
110705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
110715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
110725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
110735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
110755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
110765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
110775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1107890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
110795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
110815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
110825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
110845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
110855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
110865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
110875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
110895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
110905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
110915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1109290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
110935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
110955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
110965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
110975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
110995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
111005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
111015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (through CONNECT tunnel)
111033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
111043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
1110590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1110690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
111075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
111097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_req1(
111107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
111115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const headers[] = {
111127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetMethodKey(), "GET",
111137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
111147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetHostKey(),  "www.google.com:443",
111157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetSchemeKey(), "http",
111167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetVersionKey(), "HTTP/1.1"
111175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
11119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
11120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      headers, arraysize(headers), 0));
111215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
111235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect, 0),
111245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_req1, 2),
111255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 5),
111265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
111275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
111297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
111307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
111317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
111327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_resp1(
111337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
111347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
111357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
111367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
111377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
111385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
111395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 1),
111405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_resp1, 3),
111415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body1, 4),
111425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 6),
111435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 7),
111445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 8)
111455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
111465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeterministicSocketData data1(reads1, arraysize(reads1),
111485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                writes1, arraysize(writes1));
111495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
111505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
111515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
111532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
111542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
11155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
111565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
111577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
111595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
111607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
111635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
111665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
111685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
111695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
111705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
111715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
111735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
111745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
111755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1117690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
111775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(4);
111785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
111805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
111815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
111832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
111842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
111852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
111862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
111875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
111885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
111895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
111905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
111915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
111935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
111945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
111955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1119690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
111975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(3);
111985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
112005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
112012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
112032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
112042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The established SPDY sessions is considered reused by the HTTP request.
112052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
112062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HTTP requests over a SPDY session should have a different connection
112072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // socket_log_id than requests over a tunnel.
112082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
112095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
112105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
112125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_force_spdy_always(true);
112135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
112145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
112155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1121790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1121890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
112195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for the HTTP URL
1122090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1122190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
112225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
112245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 1),
112255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 4),
112265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
112297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
112307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
112317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
112325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
112335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 2),
112345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 3),
112355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 5),
112365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 6),
112375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 7)
112385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
112415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
112425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
112447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
112475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
112495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
112515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
112525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
112535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
112545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
112565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
112575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
112585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1125990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
112605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
112625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
112635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
112655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
112665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
112675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
112685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
112705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
112715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
112725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1127390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
112745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
112765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
112775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
112785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that in the case where we have a SPDY session to a SPDY proxy
112805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we do not pool other origins that resolve to the same IP when
112815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the certificate does not match the new origin.
112825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/134690
112837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
112845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url1 = "http://www.google.com/";
112855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url2 = "https://mail.google.com/";
112865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string ip_addr = "1.2.3.4";
112875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTP URL (through SPDY proxy)
112897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
112907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11291a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
112927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
112935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
112955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
112965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
112997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
113005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
113015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
113025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
113035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
113045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
113075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1),
113085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes1, arraysize(writes1)));
113095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
113105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
113115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
113125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK, peer_addr);
113135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->set_connect_data(connect_data1);
113145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (direct)
1131690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1131790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
113185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
113205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 0),
113215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
113247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
113255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
113265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 1),
113275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 2),
113285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
113295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
113325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
113335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes2, arraysize(writes2)));
113345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data2(ASYNC, OK);
113355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->set_connect_data(connect_data2);
113365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a proxy config that sends HTTP requests to a proxy, and
113385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all others direct.
113395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
113405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
113415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
113425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
11343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
113445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
113455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
113465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load a valid cert.  Note, that this does not need to
113485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be valid for proxy because the MockSSLClientSocket does
113495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not actually verify it.  But SpdySession will use this
113505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to see if it is valid for the new origin
113512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
113525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> server_cert(
113535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
113545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
113555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
113577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
113585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl1.cert = server_cert;
11359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
113625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
113647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
113685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
113725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
113755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
113775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
113785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
113795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(url1);
113805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
113825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
113835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
113845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
113855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->RunFor(3);
113865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback1.have_result());
113885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
113895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
113905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
113925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
113935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
113945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(url2);
113955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
113975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
113985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
113995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1140090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
114015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->RunFor(3);
114025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
114045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
114055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
114065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
114075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// error) in SPDY session, removes the socket from pool and closes the SPDY
11410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// session. Verify that new url's from the same HttpNetworkSession (and a new
11411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SpdySession) do work. http://crbug.com/224701
114127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string https_url = "https://www.google.com/";
11414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads1[] = {
11416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
11420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data1->SetStop(1);
11422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1142390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1142490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes2[] = {
11426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockWrite(*req2, 0),
11427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
114307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads2[] = {
11432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*resp2, 1),
11433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*body2, 2),
11434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, OK, 3)  // EOF
11435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
11438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
11439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  writes2, arraysize(writes2)));
11440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
114427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
11446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
114487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
11452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start the first transaction to set up the SpdySession and verify that
11457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // connection was closed.
11458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request1;
11459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.method = "GET";
11460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.url = GURL(https_url);
11461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.load_flags = 0;
11462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(MEDIUM, session.get());
11463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback1;
11464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1146690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now, start the second request and make sure it succeeds.
11470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request2;
11471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.method = "GET";
11472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.url = GURL(https_url);
11473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.load_flags = 0;
11474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
11475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback2;
11476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1147890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data2->RunFor(3);
11480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
11482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
11483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
11485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11487a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11488a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
11489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11490a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
11491a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11493a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Use two different hosts with different IPs so they don't get pooled.
11494a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11495a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11497a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11498a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
114997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11500a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
115017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11502a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11503a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11504a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1150590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11506a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11507a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy1_writes[] = {
11508a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host1_req, 1),
11509a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
115107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
115117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
115137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11514a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy1_reads[] = {
11515a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp, 2),
11516a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
11517a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11518a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11519a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11520a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy1_data(
11521a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11522a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_reads, arraysize(spdy1_reads),
11523a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_writes, arraysize(spdy1_writes)));
11524a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11525a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1152690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11527a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11528a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy2_writes[] = {
11529a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host2_req, 1),
11530a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
115317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
115327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
115347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11535a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy2_reads[] = {
11536a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp, 2),
11537a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp_body, 3),
11538a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11539a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11540a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11541a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy2_data(
11542a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11543a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_reads, arraysize(spdy2_reads),
11544a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_writes, arraysize(spdy2_writes)));
11545a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11546a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11547a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite http_write[] = {
11548a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
11549a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Host: www.a.com\r\n"
11550a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
11551a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11552a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11553a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead http_read[] = {
11554a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
11555a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11556a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Length: 6\r\n\r\n"),
11557a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("hello!"),
11558a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11559a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11560a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                     http_write, arraysize(http_write));
11561a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11562a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11563a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a("www.a.com", 443);
1156490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a(
1156590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
11566a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
115677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11568a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11569a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TestCompletionCallback callback;
11570a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request1;
11571a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.method = "GET";
11572a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.url = GURL("https://www.a.com/");
11573a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.load_flags = 0;
11574a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
11575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11576a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11577a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11578a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11579a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11580a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11581a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11582a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11584a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11585a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11586a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11587a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11588a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string response_data;
11589a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11590a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11591a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  trans.reset();
11592a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
115937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11594a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11595a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_b("www.b.com", 443);
1159690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_b(
1159790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
11598a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
115997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11600a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request2;
11601a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.method = "GET";
11602a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.url = GURL("https://www.b.com/");
11603a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.load_flags = 0;
11604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11605a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11606a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11607a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11608a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11609a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11610a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11611a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11613a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11614a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11615a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11616a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11617a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11618a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
116197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11620a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
116217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11622a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11623a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a1("www.a.com", 80);
1162490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a1(
1162590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
11626a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
116277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11628a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request3;
11629a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.method = "GET";
11630a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.url = GURL("http://www.a.com/");
11631a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.load_flags = 0;
11632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11633a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11634a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11635a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11636a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11637a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11638a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11639a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11641a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11642a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
11643a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
11644a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11645a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11646a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
116477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11648a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
116497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11650a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
11651a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
116588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
116608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
116888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
116908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
117188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
117208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
11727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
117548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
117568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(ASYNC, ERR_CONNECTION_RESET),
11760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
11763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11779eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11780eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
117908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
117928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
11796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
11797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
11798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11817eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
118288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
118308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
11834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
11835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
11836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11837eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_CONNECTION_RESET),
11839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11840eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11841eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11842eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11845eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11846eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11847eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11849eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11860eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11862eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11863eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.extra_headers.SetHeader("X-Foo", "bar");
11866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
118678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
118698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11871eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
11873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
11874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n"
11875eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "X-Foo: bar\r\n\r\n"),
11876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11878eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead("HTTP/1.1 200 OK\r\n"
11879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "Content-Length: 5\r\n\r\n"
11880eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "hello"),
11881eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_UNEXPECTED),
11882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11894eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(OK, rv);
11895eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11896eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11897eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string foo;
11899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("bar", foo);
11901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11902eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
119043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamBase that simply records calls to SetPriority().
119063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStream : public HttpStreamBase,
119073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   public base::SupportsWeakPtr<FakeStream> {
119083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
119093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit FakeStream(RequestPriority priority) : priority_(priority) {}
119103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStream() {}
119113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
119133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int InitializeStream(const HttpRequestInfo* request_info,
119153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               RequestPriority priority,
119163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const BoundNetLog& net_log,
119173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
119183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_IO_PENDING;
119193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int SendRequest(const HttpRequestHeaders& request_headers,
119223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          HttpResponseInfo* response,
119233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          const CompletionCallback& callback) OVERRIDE {
119243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
119263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
119293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
119313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
119343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
119363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
119393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
119403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
119423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Close(bool not_reusable) OVERRIDE {}
119453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsResponseBodyComplete() const OVERRIDE {
119473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
119493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool CanFindEndOfResponse() const OVERRIDE {
119523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
119533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReused() const OVERRIDE {
119563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
119583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetConnectionReused() OVERRIDE {
119613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReusable() const OVERRIDE {
119653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
119673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int64 GetTotalReceivedBytes() const OVERRIDE {
119705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ADD_FAILURE();
119715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0;
119725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
119735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
119743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool GetLoadTimingInfo(
119753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      LoadTimingInfo* load_timing_info) const OVERRIDE {
119763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
119783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
119813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLCertRequestInfo(
119853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      SSLCertRequestInfo* cert_request_info) OVERRIDE {
119863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsSpdyHttpStream() const OVERRIDE {
119903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
119923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Drain(HttpNetworkSession* session) OVERRIDE {
119953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
119963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
119993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
120003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
120033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
120043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStream);
120063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
120073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamRequest that simply records calls to SetPriority()
120093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// and vends FakeStreams with its current priority.
120103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamRequest : public HttpStreamRequest,
120113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          public base::SupportsWeakPtr<FakeStreamRequest> {
120123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
120133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
120143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    HttpStreamRequest::Delegate* delegate)
120153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : priority_(priority),
12016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(NULL) {}
12018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
12020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    HttpStreamRequest::Delegate* delegate,
12021f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : priority_(priority),
12023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(create_helper) {}
120253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamRequest() {}
120273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
120293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const WebSocketHandshakeStreamBase::CreateHelper*
12031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  websocket_stream_create_helper() const {
12032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return websocket_stream_create_helper_;
12033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
120353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create a new FakeStream and pass it to the request's
120363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // delegate. Returns a weak pointer to the FakeStream.
120373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> FinishStreamRequest() {
120383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStream* fake_stream = new FakeStream(priority_);
120393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Do this before calling OnStreamReady() as OnStreamReady() may
120403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // immediately delete |fake_stream|.
120413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
120423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
120433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return weak_stream;
120443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int RestartTunnelWithProxyAuth(
120473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const AuthCredentials& credentials) OVERRIDE {
120483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
120493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
120503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual LoadState GetLoadState() const OVERRIDE {
120533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
120543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return LoadState();
120553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
120583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
120593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool was_npn_negotiated() const OVERRIDE {
120623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
120633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual NextProto protocol_negotiated() const OVERRIDE {
120663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return kProtoUnknown;
120673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool using_spdy() const OVERRIDE {
120703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
120713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
120743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
120753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpStreamRequest::Delegate* const delegate_;
12076f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
120773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
120793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
120803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamFactory that vends FakeStreamRequests.
120823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamFactory : public HttpStreamFactory {
120833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
120843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory() {}
120853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamFactory() {}
120863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns a WeakPtr<> to the last HttpStreamRequest returned by
120883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // RequestStream() (which may be NULL if it was destroyed already).
120893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request() {
120903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return last_stream_request_;
120913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
120923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
120933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual HttpStreamRequest* RequestStream(
120943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
120953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
120963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
120973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
120983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
120993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
121003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
121013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
121023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return fake_request;
121033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
121043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
121063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
121073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
121083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
121093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
121103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
12111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebSocketHandshakeStreamBase::CreateHelper* create_helper,
121123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
12113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamRequest* fake_request =
12114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new FakeStreamRequest(priority, delegate, create_helper);
12115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
12116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return fake_request;
121173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
121183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void PreconnectStreams(int num_streams,
121203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const HttpRequestInfo& info,
121213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 RequestPriority priority,
121223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& server_ssl_config,
121233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& proxy_ssl_config) OVERRIDE {
121243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
121253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
121263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual base::Value* PipelineInfoToValue() const OVERRIDE {
121283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
121293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
121303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
121313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
121333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
121343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
121353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
121363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
121383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request_;
121393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
121413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
121423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(yhirano): Split this class out into a net/websockets file, if it is
12144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// worth doing.
12145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class FakeWebSocketStreamCreateHelper :
12146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      public WebSocketHandshakeStreamBase::CreateHelper {
12147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
12148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateBasicStream(
12149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_ptr<ClientSocketHandle> connection,
12150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool using_proxy) OVERRIDE {
12151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const base::WeakPtr<SpdySession>& session,
12157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool use_relative_url) OVERRIDE {
12158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
12161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~FakeWebSocketStreamCreateHelper() {}
12163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual scoped_ptr<WebSocketStream> Upgrade() {
12165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return scoped_ptr<WebSocketStream>();
12167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
12169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
121703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
121713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority to its
121733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// stream request on start.
121743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
121753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
121763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
121773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
121793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
121813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
121833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
121853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
121863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
121873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
121883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
121903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
121913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
121923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
121933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
121943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
121963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream request.
121973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
121983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
121993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
122003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
122023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
122043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
122063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
122073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
122083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
122093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
122113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
122123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
122133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
122143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
122163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
122173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_request->priority());
122183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
122193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
122213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream.
122223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
122233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
122243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
122253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
122273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
122293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
122313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
122323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
122333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
122343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
122363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
122373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
122383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
122393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_stream != NULL);
122403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_stream->priority());
122413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
122433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_stream->priority());
122443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
122453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The same logic needs to be tested for both ws: and wss: schemes, but this
12248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // test is already parameterised on NextProto, so it uses a loop to verify
12249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // that the different schemes work.
12250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < arraysize(test_cases); ++i) {
12252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpNetworkSessionPeer peer(session);
12254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamFactory* fake_factory = new FakeStreamFactory();
12255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetHttpStreamFactoryForWebSocket(
12257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<HttpStreamFactory>(fake_factory));
12258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpNetworkTransaction trans(LOW, session);
12260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trans.SetWebSocketHandshakeStreamCreateHelper(
12261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &websocket_stream_create_helper);
12262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpRequestInfo request;
12264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TestCompletionCallback callback;
12265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.method = "GET";
12266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.url = GURL(test_cases[i]);
12267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
12269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              trans.Start(&request, callback.callback(), BoundNetLog()));
12270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::WeakPtr<FakeStreamRequest> fake_request =
12272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        fake_factory->last_stream_request();
12273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(fake_request != NULL);
12274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(&websocket_stream_create_helper,
12275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_request->websocket_stream_create_helper());
12276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
12278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
122793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a used socket is returned to the SSL socket pool, it's closed
122803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// if the transport socket pool is stalled on the global socket limit.
122813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
122823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
122833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
122843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
122853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
122863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up SSL request.
122883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
122903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
122913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.google.com/");
122923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite ssl_writes[] = {
122943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
122953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
122963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
122973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
122983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead ssl_reads[] = {
122993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
123003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
123013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("hello world"),
123023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
123033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
123043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
123053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    ssl_writes, arraysize(ssl_writes));
123063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
123073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
123093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
123103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
123123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
123143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
123153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
123163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
123183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
123193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
123203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
123213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
123223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
123233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
123243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
123253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
123263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
123273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
123283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
123293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
123303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
123313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
123333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the SSL request.
123353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback ssl_callback;
123363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> ssl_trans(
123373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
123383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
123393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            ssl_trans->Start(&ssl_request, ssl_callback.callback(),
123403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            BoundNetLog()));
123413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
123433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
123443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
123453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
123463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
123473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
123483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
123493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(IsTransportSocketPoolStalled(session));
123503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Wait for response from SSL request.
123523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ssl_callback.WaitForResult());
123533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
123543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
123553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
123563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL socket should automatically be closed, so the HTTP request can
123583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // start.
123593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
123603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(IsTransportSocketPoolStalled(session));
123613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The HTTP request can now complete.
123633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
123643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
123653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
123663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
123683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
123693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a SSL connection is established but there's no corresponding
123713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// request that needs it, the new socket is closed if the transport socket pool
123723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// is stalled on the global socket limit.
123733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
123743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
123753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
123763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
123773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
123783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up an ssl request.
123803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
123823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
123833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.foopy.com/");
123843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // No data will be sent on the SSL socket.
123863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data;
123873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
123883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
123903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
123913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
123933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
123953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
123963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
123973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
123993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
124003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
124013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
124023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
124033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
124043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
124053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
124063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
124073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
124083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
124093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
124103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
124113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
124123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
124163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // cancelled when a normal transaction is cancelled.
124173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
124183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::SSLConfig ssl_config;
124193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session->ssl_config_service()->GetSSLConfig(&ssl_config);
124203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
124213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                         ssl_config, ssl_config);
124223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
124233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
124253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
124263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
124273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
124283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
124293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
124303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
124313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(IsTransportSocketPoolStalled(session));
124323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL connection will automatically be closed once the connection is
124343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // established, to let the HTTP request start.
124353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
124363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
124373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
124383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
124393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
124413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
124423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
12444