http_network_transaction_unittest.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_file_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/capturing_net_log.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info_test_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/request_priority.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_data_directory.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_file_element_reader.h"
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/mock_cert_verifier.h"
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/dns/host_cache.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_digest.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_mock.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_ntlm.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_basic_stream.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session_peer.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_server_properties_impl.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_transaction_unittest.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_fixed.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_service.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h"
51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/socket/client_socket_pool_manager.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/mock_client_socket_pool_manager.h"
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_test_util.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_framer.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h"
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/spdy/spdy_test_util_common.h"
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_config_service_defaults.h"
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_info.h"
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/cert_test_util.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "url/gurl.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar(ASCIIToUTF16("bar"));
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar2(ASCIIToUTF16("bar2"));
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar3(ASCIIToUTF16("bar3"));
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBaz(ASCIIToUTF16("baz"));
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFirst(ASCIIToUTF16("first"));
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo(ASCIIToUTF16("foo"));
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo2(ASCIIToUTF16("foo2"));
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo3(ASCIIToUTF16("foo3"));
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFou(ASCIIToUTF16("fou"));
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kSecond(ASCIIToUTF16("second"));
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetTransportSocketPool(
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetSSLSocketPool(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes in a Value created from a NetLogHttpResponseParameter, and returns
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a JSONified list of headers as a single string.  Uses single quotes instead
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of double quotes for easier comparison.  Returns false on failure.
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::ListValue* header_list;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->GetList("headers", &header_list))
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string double_quote_headers;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(header_list, &double_quote_headers);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReplaceChars(double_quote_headers, "\"", "'", headers);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.send_start.is_null());
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int connect_timing_flags) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   connect_timing_flags);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    int connect_timing_flags) {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   connect_timing_flags);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SpdySessionDependencies::SpdyCreateSession(session_deps);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HttpNetworkTransactionTest
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public PlatformTest,
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      public ::testing::WithParamInterface<NextProto> {
214a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) public:
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~HttpNetworkTransactionTest() {
216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Important to restore the per-pool limit first, since the pool limit must
217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // always be greater than group limit, and the tests reduce both limits.
218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_pool(
219a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
220a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_group(
221a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
223a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HttpNetworkTransactionTest()
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      : spdy_util_(GetParam()),
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        session_deps_(GetParam()),
228a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)),
230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)) {
232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SimpleGetHelperResult {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status_line;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Empty the current queue.
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformTest::TearDown();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HttpStreamFactory::set_use_alternate_protocols(false);
255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This is the expected return from a current server advertising SPDY.
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string GetAlternateProtocolHttpHeader() {
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        std::string("Alternate-Protocol: 443:") +
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "\r\n\r\n";
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either |write_failure| specifies a write failure or |read_failure|
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specifies a read failure when using a reused socket.  In either case, the
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // failure should cause the network transaction to resend the request, and the
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other argument should be NULL.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const MockRead* read_failure);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               size_t data_count) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CapturingBoundNetLog log;
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.net_log = log.bound().net_log();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY,
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   CreateSession(&session_deps_)));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < data_count; ++i) {
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(data[i]);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(log.bound().IsLoggingAllEvents());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), log.bound());
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = callback.WaitForResult();
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Even in the failure cases that use this function, connections are always
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // successfully established before the error.
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (out.rv != OK)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Can't use ASSERT_* inside helper functions like this, so
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // return an error.
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (response == NULL || response->headers.get() == NULL) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.rv = ERR_UNEXPECTED;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.status_line = response->headers->GetStatusLine();
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ("127.0.0.1", response->socket_address.host());
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(80, response->socket_address.port());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &out.response_data);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::CapturingNetLog::CapturedEntryList entries;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.GetEntries(&entries);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t pos = ExpectLogContainsSomewhere(
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectLogContainsSomewhere(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, pos,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string line;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("GET / HTTP/1.1\r\n", line);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpRequestHeaders request_headers;
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string value;
340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Host", &value));
341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("www.google.com", value);
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("keep-alive", value);
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string response_headers;
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              response_headers);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        size_t reads_count) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider* data[] = { &reads };
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SimpleGetHelperForData(data, 1);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int expected_status);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelper(const MockRead& status);
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void BypassHostCacheOnRefreshHelper(int load_flags);
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CheckErrorIsPassedBack(int error, IoMode mode);
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
369a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SpdyTestUtil spdy_util_;
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionDependencies session_deps_;
371a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
372a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Original socket limits.  Some tests set these.  Safest to always restore
373a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // them once each test has been run.
374a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_group_sockets_;
375a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_pool_sockets_;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NextProto,
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    HttpNetworkTransactionTest,
381558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
382558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                    kProtoHTTP2Draft04));
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fill |str| with a long header list that consumes >= |size| bytes.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillLargeHeadersString(std::string* str, int size) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* row =
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_row = strlen(row);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int num_rows = static_cast<int>(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ceil(static_cast<float>(size) / sizeof_row));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_data = num_rows * sizeof_row;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(sizeof_data >= size);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  str->reserve(sizeof_data);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < num_rows; ++i)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str->append(row, sizeof_row);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alternative functions that eliminate randomness and dependency on the local
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// host name so that the generated NTLM messages are reproducible.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom1(uint8* output, size_t n) {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom2(uint8* output, size_t n) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MockGetHostName() {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "WTC-WIN7";
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CaptureGroupNameSocketPool : public ParentPool {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureGroupNameSocketPool(HostResolver* host_resolver,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CertVerifier* cert_verifier);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string last_group_name_received() const {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return last_group_name_;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int RequestSocket(const std::string& group_name,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const void* socket_params,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            RequestPriority priority,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ClientSocketHandle* handle,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const CompletionCallback& callback,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const BoundNetLog& net_log) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_group_name_ = group_name;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_IO_PENDING;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(const std::string& group_name,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ClientSocketHandle* handle) {}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseSocket(const std::string& group_name,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             StreamSocket* socket,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int id) {}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CloseIdleSockets() {}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCount() const {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCountInGroup(const std::string& group_name) const {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(const std::string& group_name,
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const ClientSocketHandle* handle) const {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta ConnectionTimeout() const {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta();
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string last_group_name_;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameTransportSocketPool;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSOCKSSocketPool;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier)
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : SSLClientSocketPool(0,
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          0,
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          host_resolver,
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          cert_verifier,
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          std::string(),
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL) {}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for validating that AuthChallengeInfo's are correctly
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// configured for common cases.
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(auth_challenge->is_proxy);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digestive", auth_challenge->realm);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digest", auth_challenge->scheme);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(), auth_challenge->realm);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("ntlm", auth_challenge->scheme);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Basic) {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGET) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Response with no status line.
5797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
5927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Beyond 4 bytes of slop and it should fail to find a status line.
6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Q"),
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("J"),
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Close the connection before enough bytes to have a status line.
6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTT"),
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTT", out.response_data);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulate a 204 response, lacking a Content-Length header, sent over a
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// persistent connection.  The response should still terminate since a 204
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cannot have a response body.
6637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StopsReading204) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", out.response_data);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple request using chunked encoding with some extra data after.
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (Like might be seen in a pipelined response.)
6787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/56344.
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersNoTransferEncoding) {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n"),
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DuplicateContentLengthHeadersNoTransferEncoding) {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n"),
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ComplexContentLengthHeadersNoTransferEncoding) {
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More than 2 dupes.
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP/1.0
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 dupes and one mismatched.
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersTransferEncoding) {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 666\r\n"),
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1337\r\n"),
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Transfer-Encoding: chunked\r\n\r\n"),
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/98895.
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that a single Content-Disposition header results in no error.
7947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Content-Disposition headers result in no error.
8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       TwoIdenticalContentDispositionHeaders) {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"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.1 200 OK", out.status_line);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Content-Disposition headers result in an error.
8267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Location headers result in no error.
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also tests Location header behavior.
8417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://redirect.com/");
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://good.com/", url);
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Location headers result in an error.
8787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://evil.com/\r\n"),
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Do a request using the HEAD method. Verify that we don't try to read the
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message body (since HEAD has none).
8937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Head) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Server: Blah\r\n"),
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1234\r\n\r\n"),
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the headers got parsed.
934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1234, response->headers->GetContentLength());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_header;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* iter = NULL;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_server_header = response->headers->EnumerateHeader(
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &iter, "Server", &server_header);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(has_server_header);
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Blah", server_header);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reading should give EOF right away, since there is no message body
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (despite non-zero content-length).
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExpectedResponseData[] = {
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores100) {
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadDataStream upload_data_stream(&element_readers, 0);
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is almost the same as Ignores100 above, but the response contains
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTP/1.1 and the two status headers are read in one read.
10477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HTTP/1.1 200 OK\r\n\r\n"),
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* write_failure,
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* read_failure) {
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Written data for successfully sending both requests.
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data1_writes[] = {
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read results for the first request.
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_failure) {
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(!read_failure);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_writes[1] = *write_failure;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(read_failure);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_reads[2] = *read_failure;
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data1_writes, arraysize(data1_writes));
1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The second request should be using a new socket.
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       KeepAliveConnectionNotConnectedOnWrite) {
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(&write_failure, NULL);
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
1255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What do various browsers do when the server closes a non-keepalive
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection without sending any response header or body?
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IE7: error page
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Safari 3.1.2 (Windows): error page
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Firefox 3.0.1: blank page
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opera 9.52: after five attempts, blank page
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us: error page (EMPTY_RESPONSE)
12877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // EOF
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests. There was a bug causing HttpNetworkTransaction to hang in the
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor in such situations.
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/154712 and http://crbug.com/156609.
13037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, rv);
1336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
134090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
137890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we correctly reuse a keep-alive connection after not explicitly
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reading the body.
13847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that because all these reads happen in the same
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StaticSocketDataProvider, it shows that the same socket is being reused for
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all transactions.
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumUnreadBodies = arraysize(data1_reads) - 2;
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_lines[kNumUnreadBodies];
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingReused(load_timing_info);
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(response->headers.get() != NULL);
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_lines[i] = response->headers->GetStatusLine();
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We intentionally don't read the response bodies.
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kStatusLines[] = {
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 204 No Content",
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 205 Reset Content",
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 304 Not Modified",
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 forgot_to_update_kStatusLines);
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumUnreadBodies; ++i)
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kStatusLines[i], response_lines[i]);
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
1483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello", response_data);
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth.
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (basic auth is the easiest to mock, because it has no randomness).
14937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuth) {
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
1503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have a new socket ID, and times after
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.connect_timing.connect_start);
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
1596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection.
16317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
1639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a regression where we disconnect a Keep-Alive
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection during an auth roundtrip, we'll end up reading this.
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
1678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have the same socket ID, and times
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.send_start);
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with no response body to drain.
17257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
1767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with a large response body to drain.
18017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 5 kb of response body.
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_body_string("Unauthorized");
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append(5 * 1024, ' ');
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append("\r\n");
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 5134 = 12 + 5 * 1024 + 2
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5134\r\n\r\n"),
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
1851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection, but the server gets impatient and closes the connection.
18857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This simulates the seemingly successful write to a closed connection
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if the bug is not fixed.
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tell MockTCPClientSocket to simulate the server closing the connection.
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
1937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a connection
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that requires a restart when setting up an SSL tunnel.
19717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
1979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
19802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
1982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
1983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello"),
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
20532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT requests and responses are handled at the connect job level, so
20542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the transaction does not yet have a connection.
20552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
20562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
20782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
20792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
20802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy connection, when setting up an SSL tunnel.
20877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that proxy authentication is attempted even
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0123456789"),
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong credentials (wrong password).
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrong password (should be "bar").
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBaz), callback2.callback());
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the NetLog and HttpNetworkTransaction go
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // out of scope.
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't read the response body when we fail to establish a tunnel,
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// even if the user cancels the proxy's auth attempt.
21917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407.
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
2222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
22507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are using a DIRECT connection (i.e. no proxy) for this session.
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
22582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
2259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through a non-authenticating proxy. The request should fail with
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ERR_UNEXPECTED_PROXY_AUTH.
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that it is impossible to detect if an HTTP server returns a 407 through
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a non-authenticating proxy - there is nothing to indicate whether the
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// response came from the proxy or the server, so it is treated as if the proxy
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// issued the challenge.
22957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       HttpsServerRequestsProxyAuthThroughProxy) {
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Unauthorized\r\n"),
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\n"),
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy.
23547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
23552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
23562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
23572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
23582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
23602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
23612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
23622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
23652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("PROXY myproxy:70"));
23662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
23712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
23722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
23742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
23752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
23772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
23782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
23792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
23812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
23822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
23832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
23842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
23862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
23872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
23882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
23892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
23912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
23922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
23932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
23952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
23962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
23972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
23982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
24002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
24022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
24062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
24102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
24132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
24142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
24162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
24182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
24192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
24212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
24222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
24232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
24252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
24272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
24312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
24342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
24352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
24372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
24392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
24402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
24422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
24432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
24442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
24462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
24482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
24492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
24502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
24527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
24532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
24542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
24552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
24562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
24582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
24592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
24602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
24632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
24642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
24692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
24702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
24712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
24722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
24732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
24752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
24762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
24772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
24792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
24802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
24812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
24822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
24842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
24852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
24862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
24872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
24892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
24902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
24912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
24932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
24942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
24952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
24962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
24982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
25002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
25022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
25042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
25082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
25112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
25122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
25142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
25162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
25172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
25192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
25202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
25212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
25222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
25242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
25262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
25302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
25332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
25342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
25362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
25392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
25472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a simple get through an HTTPS Proxy.
25517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
25952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
25962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
25972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
25982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
26127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch http://www.google.com/ via SPDY
262690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
262790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
26317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
26457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
26602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
26612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
26622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
26757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
2682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request will be a bare GET, the second request will be a
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GET with a Proxy-Authorization header.
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get(
269190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthorizationHeaders[] = {
269390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authorization", "Basic Zm9vOmJhcg=="
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get_authorization(
269690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
269790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  arraysize(kExtraAuthorizationHeaders) / 2,
269890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false,
269990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  3,
270090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  LOWEST,
270190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false));
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get, 1),
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get_authorization, 4),
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first response is a 407 proxy authentication challenge, and the second
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response will be a 200 response since the second request includes a valid
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Authorization header.
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthenticationHeaders[] = {
271190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\""
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_authentication(
27147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError(
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "407 Proxy Authentication Required",
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1));
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_authentication(
27197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
27207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_data(
27217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
27227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_authentication, 2),
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_authentication, 3),
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_data, 5),
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_data, 6),
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
27377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response = trans->GetResponseInfo();
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response_restart != NULL);
2771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response_restart->headers.get() != NULL);
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response_restart->headers->response_code());
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
27787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
279590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
28027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
28037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
28047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 10\r\n\r\n";
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
28087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
28107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
281290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
281790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateMockWrite(*window_update, 5),
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 7, ASYNC),
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
28347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.was_npn_negotiated = false;
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
2839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
28502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
28512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
28522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1234567890", response_data);
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
28647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
288190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via SPDY
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kMyUrl = "https://www.google.com/";
288490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
288590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
28867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
28877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get, 1));
28887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
28897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
28907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp(
28917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
28937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
28947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
28957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
28967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body, 1));
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_get_resp(
289890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_body(
290090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_get_resp, 5),
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_body, 7),
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
29227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
29257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
29267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.protocol_negotiated = GetParam();
2927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
29382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
29392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
29402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT failure through an HTTPS Proxy.
29527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
296990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
297090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
297190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*get, 3),
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
29797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 2, ASYNC),
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
29917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
2992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
29947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
2995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
30092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to different servers.
30107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
30112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
30122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
30142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
30152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
30172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
30192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
30212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
30222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
30232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
30242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
30262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
30272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://news.google.com/");
30282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
30292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
303190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
30327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
30337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
30362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
30372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
30382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
30392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
30407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
30412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
30422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
30432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
30447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
30457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
30467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
30472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
304890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
30492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to news.google.com:443 via SPDY.
30512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* const kConnectHeaders2[] = {
30527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetMethodKey(), "CONNECT",
30537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetPathKey(), "news.google.com:443",
30547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetHostKey(), "news.google.com",
30557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetVersionKey(), "HTTP/1.1",
30562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
30572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(
3058a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      spdy_util_.ConstructSpdyControlFrame(NULL,
3059a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0,
3060a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           /*compressed*/ false,
3061a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           3,
3062a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           LOWEST,
3063a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           SYN_STREAM,
3064a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           CONTROL_FLAG_NONE,
3065a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           kConnectHeaders2,
3066a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           arraysize(kConnectHeaders2),
3067a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0));
30687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp2(
30697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
30702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://news.google.com/ via HTTP.
30722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET / HTTP/1.1\r\n"
30732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: news.google.com\r\n"
30742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
30752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
30767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
30772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
30782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
30792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
30807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
30812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
30827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
30832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
30852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
30862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
30872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect2, 5),
30882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 7),
30892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
30902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
30922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
30932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
30942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
30952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp2, 6, ASYNC),
30962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
30972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 9, ASYNC),
30982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 10),
30992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
31002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
31022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
31032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
31052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
31077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
31092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
31102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
31112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
31132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl3(ASYNC, OK);
31142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.was_npn_negotiated = false;
31152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.protocol_negotiated = kProtoUnknown;
3116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
31172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
31192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
31222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
31232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
31242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
31252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
31262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
31282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
31292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
31312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
31322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
31332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
31352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
31372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
31382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
31402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
31422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
31452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
31462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
31472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second connect and request, each of their responses, and the body.
31492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
31502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
31512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
31522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
31542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
31552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Even though the SPDY connection is reused, a new tunnelled connection has
31562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to be created, so the socket's load timing looks like a fresh connection.
31572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
31582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have different IDs, since they each are using their own
31602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // separate stream.
31612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
31622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
31642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
31652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
31672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to the same server.
31687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
31692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
31702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
31722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
31732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
31752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
31772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
31792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
31802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
31812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
31822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
31842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
31852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
31862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
31872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
318990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
31907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
31917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
31922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
31942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
31952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
31962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
31972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
31987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
31992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
32002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
32012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
32027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
32037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
32047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
32052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
320690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
32072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/2 via HTTP.
32092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET /2 HTTP/1.1\r\n"
32102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
32112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
32122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
32137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
32142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
32152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
32162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
32177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
32182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
32197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
32202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
32222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
32232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
32242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 5),
32252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
32262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
32282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
32292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
32302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
32312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
32322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 7, ASYNC),
32332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 8),
32342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
32352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
32372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
32382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
32402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
32427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
32442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
32452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
32462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
32482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
32502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
32542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
32562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
32572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
32592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
32602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
32622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
32632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
32642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
32662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
32682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
32692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
32712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
32732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
32742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
32782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second request, response, and body.  There should not be a second
32812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connect.
32822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(3);
32832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
32842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
32852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
32872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
32882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
32892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
32912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
32922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
32942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
32952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
32972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Proxy to different servers.
32987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
32992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyLoadTimingTwoHttpRequests) {
33002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
33022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
33032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
33052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
33072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
33092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
33102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("http://www.google.com/");
33112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
33122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
33142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
33152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("http://news.google.com/");
33162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
33172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://www.google.com/
33197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
33207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3321a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
33227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
33237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp1(
33247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(
33267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
33272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://news.google.com/
33297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers2(
33307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3331a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
33327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
33337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp2(
33347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
33357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(
33367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
33372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
33392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get1, 0),
33402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get2, 3),
33412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
33422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
33442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp1, 1, ASYNC),
33452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body1, 2, ASYNC),
33462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp2, 4, ASYNC),
33472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body2, 5, ASYNC),
33482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 6),
33492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
33502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
33522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
33532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
33552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
33577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
33592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
33612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
33642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
33652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
33662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
33672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
33692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
33702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
33722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
33732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
33742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
33752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
33772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
33792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
33802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
33822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
33842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
33852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, callback.WaitForResult());
33862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete the first request, so the second one can reuse the socket.
33872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
33882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
33912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
33922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
33932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
33952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
33962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
33972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
33992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
34002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
34012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
34032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
34042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
34062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
34072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, callback.WaitForResult());
34082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
34092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the challenge-response-retry sequence through an HTTPS Proxy
34117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the GET with a 407, using a persistent
34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: keep-alive\r\n"),
34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
3456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
3458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
34722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
34732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
34742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
34752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  load_timing_info = LoadTimingInfo();
34932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
34942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Retrying with HTTP AUTH is considered to be reusing a socket.
34952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info);
34962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status, int expected_status) {
35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
3517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status,
35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
3537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_status, rv);
35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelper(
35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status) {
35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status, ERR_TUNNEL_CONNECTION_FAILED);
35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ERR_PROXY_AUTH_UNSUPPORTED);
36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the flow when both the proxy server AND origin server require
37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authentication. Again, this uses basic auth for both since that is
37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the simplest to mock.
37247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
37332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
3734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateSession(&session_deps_)));
37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Unauthorized\r\n"),
37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the first time, this is the
37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request we should be issuing -- the final header line contains the
37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy's credentials.
37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the proxy server lets the request pass through to origin server.
37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin server responds with a 401.
37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: We are using the same realm-name as the proxy server. This is
37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // completely valid, as realms are unique across hosts.
37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 2000\r\n\r\n"),
37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the second time, we should send
37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the credentials for both the proxy and origin server.
37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly we get the desired content.
37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
3801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
3802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
3803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo2, kBar2), callback3.callback());
38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NTLM implementation using SSPI, we skip the NTLM tests since we
38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can't hook into its internals to cause it to generate predictable NTLM
38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authorization headers.
38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE)
38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The NTLM authentication unit tests were generated by capturing the HTTP
38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests and responses using Fiddler 2 and inspecting the generated random
38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes in the debugger.
38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter the correct password and authenticate successfully.
38537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
3861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ahlhx5I=\r\n\r\n"),
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
3932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
3933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter a wrong password, and then the correct one.
39827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
3990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "4Ww7b7E=\r\n\r\n"),
40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong password.
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "+4MUm7c=\r\n\r\n"),
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enter the wrong password.
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now enter the right password.
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback4.callback());
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback5;
41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One more roundtrip
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback5.WaitForResult();
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NTLM_PORTABLE
41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test reading a server response which has only headers, and no body.
41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After some maximum number of bytes is consumed, the transaction should
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
41847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
41912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
4192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 300 kb of headers (we should fail after 256 kb).
41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_headers_string;
41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillLargeHeadersString(&large_headers_string, 300 * 1024);
41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\nBODY"),
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we don't try to reuse a TCPClientSocket when failing to
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// establish tunnel.
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/chromium/issues/detail?id=3772
42227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DontRecycleTransportSocketForSSLTunnel) {
42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
4230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 404, using a persistent
42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection. Usually a proxy would return 501 (not implemented),
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or 200 (tunnel established).
42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
4255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
427090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the TCPClientSocket was not added back to
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool.
4274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
427690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the socket didn't get recycled after calling the destructor.
4278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after reading all of the response body.
42827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A part of the response body is received with the response headers.
42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The rest of the response body is received in two parts.
42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("lo"),
42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" world"),
42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", status_line);
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
433090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a SSL socket after reading all of the response
43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// body.
43387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
4358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
43672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
438990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the pool and make sure that we recover okay.
43977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0)   // EOF
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
4422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
4430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
44352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
445790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start the second transaction, which should reuse the previous socket.
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
448490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after a zero-length response.
44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/9880
44927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "e=17259,18167,19592,19773,19981,20133,20173,20233&"
44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "rt=prt.2642,ol.2649,xjs.2951");
44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n"
45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n"
45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html\r\n\r\n"),
45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
454190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
45482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
45492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
45502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadDataStream upload_data_stream(&element_readers, 0);
45512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request[2];
45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: a GET request that succeeds.  The socket is recycled
45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after use.
45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].method = "GET";
45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].url = GURL("http://www.google.com/");
45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].load_flags = 0;
45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: a POST request.  Reuses the socket kept alive from
45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 1.  The first attempts fails when writing the POST data.
45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This causes the transaction to retry with a new socket.  The second
45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempt succeeds.
45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].method = "POST";
45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].url = GURL("http://www.google.com/login.cgi");
45642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request[1].upload_data_stream = &upload_data_stream;
45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].load_flags = 0;
45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first socket is used for transaction 1 and the first attempt of
45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 1.
45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of transaction 1 and the first attempt of
45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 64),  // GET
45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second socket is used for the second attempt of transaction 2.
45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 2.
45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("welcome"),
45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of the second attempt of transaction 2.
45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 3),  // POST data
46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello world", "welcome"
46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
4613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is
46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an identity in the URL. The request should be sent as normal, but when
46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it fails the identity from the URL is used to answer the challenge.
46397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:b@r@www.google.com/");
46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
46462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
4647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password contains an escaped character -- for this test to pass it
46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will need to be unescaped by HttpNetworkTransaction.
46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("b%40r", request.url.password());
46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, b@r) to answer the challenge.
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
4685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity in URL worked.
47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
471190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is an
47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// incorrect identity in the URL. The identity from the URL should be used only
47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once.
47177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: the URL has a username:password in it.  The password "baz" is
47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wrong (should be "bar").
47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:baz@www.google.com/");
47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
47272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
4728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, baz) to answer the challenge.
47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity supplied by the user (foo, bar) to answer the challenge.
47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
47975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity worked.
48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
482190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that previously tried username/passwords for a realm get re-used.
48257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
4826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
4836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
48565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
4870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
4871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
48975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: authenticate (foo2, bar2) on MyRealm2
49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as MyRealm1.
49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
4912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // Send preemptive authorization for MyRealm1
49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The server didn't like the preemptive authorization, and
49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // challenges us for a different realm (MyRealm2).
49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b 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 Zm9vMjpiYXIy\r\n\r\n"),
49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
4950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
4951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
49525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
49565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response->auth_challenge.get());
49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(response->auth_challenge->is_proxy);
49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("www.google.com:80",
49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              response->auth_challenge->challenger.ToString());
49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("basic", response->auth_challenge->scheme);
49695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo2, kBar2), callback2.callback());
49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
49845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
49865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 3: Resend a request in MyRealm's protection space --
49885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // succeed with preemptive authorization.
49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
49925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z2");
49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
4996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
49995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
50005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
50015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
50025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // The authorization for MyRealm1 gets sent preemptively
50035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // (since the url is in the same protection space)
50045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
50055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
50065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the preemptive authorization
50085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
50095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
50105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
50115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
50125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
50135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
50155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
50175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
50195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
50225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
50245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
50275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
50285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
50305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
50315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
50325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
50345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 4: request another URL in MyRealm (however the
50365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url is not known to belong to the protection space, so no pre-auth).
50375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
50385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
50395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
50405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/1");
50415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
50425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
50455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
50475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
50485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
50495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
50505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
50515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
50535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
50545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
50555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
50565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
50575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
50585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from MyRealm's cache.
50605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
50615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
50625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
50635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
50645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
50655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
50665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
50685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
50695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
50715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
50725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
50735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
50765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
50775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
50805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
50825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
50845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
50875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
50935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 5: request a URL in MyRealm, but the server rejects the
51065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cached identity. Should invalidate and re-prompt.
51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
51085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/p/q/t");
51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
51125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from cache for MyRealm.
51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever rejects the authorization.
51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // At this point we should prompt for new credentials for MyRealm.
51465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart with username=foo3, password=foo4.
51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes3[] = {
51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads3[] = {
51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
51625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
51635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
51645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
51655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
51665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes3, arraysize(data_writes3));
5167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
5169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data3);
51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
51785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
51805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
51845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
51865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
51885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
51895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
51905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback3;
51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo3, kBar3), callback3.callback());
51955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback3.WaitForResult();
51985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
51995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
52015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
52025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
52035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that nonce count increments when multiple auth attempts
52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are started with the same nonce.
52097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::Factory* digest_factory =
52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::Factory();
52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  digest_factory->set_nonce_generator(nonce_generator);
5215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(digest_factory);
5216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
52175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
52195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
52465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
52475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
52485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
52495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
52505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
52515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
52615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
52645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
52665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
52685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
52695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
52715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
52725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
52755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
52785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
52815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
52825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
52855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
52875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
52885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
52895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
52905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
52925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: Request another resource in digestive's protection space.
52945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will preemptively add an Authorization header which should have an
52955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "nc" value of 2 (as compared to 1 in the first use.
52965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
52975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
52985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
52995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
53005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as digest.
53015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
53025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
53035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
53065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
53085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
53095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
53115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
53125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
53135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
53145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
53155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
53185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
53195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
53205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
53215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
53225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
53255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
53275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
53295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
53315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
53325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
53345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
53355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
53375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
53385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
53395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
53405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
53415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the ResetStateForRestart() private method.
53437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
53445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a transaction (the dependencies aren't important).
53455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
53462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
5347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
53485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup some state (which we expect ResetStateForRestart() will clear).
53505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_ = new IOBuffer(15);
53515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_len_ = 15;
53525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->request_headers_.SetHeader("Authorization", "NTLM");
53535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup state in response_
53555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpResponseInfo* response = &trans->response_;
53565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->auth_challenge = new AuthChallengeInfo();
53575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
53585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->response_time = base::Time::Now();
53595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->was_cached = true;  // (Wouldn't ever actually be true...)
53605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { // Setup state for response_.vary_data
53625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
53635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
53645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::replace(temp.begin(), temp.end(), '\n', '\0');
53655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
53665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("Foo", "1");
53675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("bar", "23");
5368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
53695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
53705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cause the above state to be reset.
53725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->ResetStateForRestart();
53735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the state that needed to be reset, has been reset.
53755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->read_buf_.get() == NULL);
53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, trans->read_buf_len_);
53775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->request_headers_.IsEmpty());
53785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() == NULL);
53805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_cached);
53815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, response->ssl_info.cert_status);
53825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->vary_data.is_valid());
53835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
53845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate
53867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
53875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
53885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
53895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
53932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
5394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
53975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
54045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
54055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
54065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
54075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate;
54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
54195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
54295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
54325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
54335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
54355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through a
54415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy
54427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite proxy_writes[] = {
54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
54585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
54595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
54605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
54665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
54675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
54685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
54765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
54775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_reads, arraysize(proxy_reads),
54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_writes, arraysize(proxy_writes));
54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
5494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
54972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY,
5498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   CreateSession(&session_deps_)));
54995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartIgnoringLastError(callback.callback());
55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site, going through an HTTPS proxy
55217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
5522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
55232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
55242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
5525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
55335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
55395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
55405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
55425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
55435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
55445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
55455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
55612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
5562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
55635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
55655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
55765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
55772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
55792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
55802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
55812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS Proxy's ability to redirect a CONNECT request
55857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
5586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
55872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
55882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
5589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
55905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
55925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
55935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
55945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
55955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
55985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://login.example.com/\r\n"),
56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
56155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
56192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
5620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
56265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
56275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
56285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
56305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
56352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
56362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In the case of redirects from proxies, HttpNetworkTransaction returns
56372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timing for the proxy connection instead of the connection to the host,
56382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and no send / receive times.
56392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
56402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
56412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
56422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
56432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
56442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
56452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
56462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
56472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
56482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
56492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
56502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
56512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectConnectTimingHasTimes(
56522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      load_timing_info.connect_timing,
56532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
56542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
56552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_start.is_null());
56562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_end.is_null());
56572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
56617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
5662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
56665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
567090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
567190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> goaway(
567290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
5675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
56837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
56845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
56855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
56865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2),  // EOF
56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
56945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
56957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
56965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
57032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
5704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
57145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
57165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
57175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an HTTPS proxy's response to a CONNECT request is filtered.
57227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaHttpsProxy) {
5724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
57335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
57345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
57365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
57395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
57405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 23\r\n\r\n"),
57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("The host does not exist"),
57425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
57435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
57465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
57475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
57485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
57535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
57552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
5756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
57575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
57595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
57605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
57625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
57635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
57655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a SPDY proxy's response to a CONNECT request is filtered.
57687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
57695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaSpdyProxy) {
5770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
5771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     ProxyService::CreateFixed("https://proxy:70"));
57725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
57745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
57755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
57765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
57775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
577890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
577990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
578090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
57825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
57835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
57875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
57885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
57895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
57905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
57917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
57925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
57935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(
57947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(
57957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          1, "The host does not exist", 23, true));
57965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
57985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body.get(), 2, SYNCHRONOUS),
57995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),  // EOF
58005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
58015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
58035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
58045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
58055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
58065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
58077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
58085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
58115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
58135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
58152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
5816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
58175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
58205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
58225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
58255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
58265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, through
58285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a SPDY proxy over a single SPDY session.
58297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
58305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
58315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
58325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
58335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
58345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
58355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
5837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
58382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
58395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
5840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
5841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
58425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
584490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
584590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
584690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
58495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
58505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthCredentials[] = {
58515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-authorization", "Basic Zm9vOmJhcg==",
58525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
585390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
585490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      kAuthCredentials, arraysize(kAuthCredentials) / 2, 3));
58555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
58565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
58575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
58585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
58595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
58607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
58615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 1, ASYNC),
58645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 4, ASYNC),
58655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect2, 5),
58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_get, 8),
58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
58705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
58715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthChallenge[] = {
58727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
58737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetVersionKey(), "HTTP/1.1",
58745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\"",
58755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
58765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_auth_resp(
5878a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      spdy_util_.ConstructSpdyControlFrame(NULL,
5879a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0,
5880a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           false,
5881a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           1,
5882a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           LOWEST,
5883a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           SYN_REPLY,
5884a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           CONTROL_FLAG_NONE,
5885a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           kAuthChallenge,
5886a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           arraysize(kAuthChallenge),
5887a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0));
58885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
58907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
58915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
58925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 5\r\n\r\n";
58935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
58957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
58965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
58977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
58985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
58995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_auth_resp, 2, ASYNC),
59005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 6, ASYNC),
59015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 9, ASYNC),
59025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 10, ASYNC),
59035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
59045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
59075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
59085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
5909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
59105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
59115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
59127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
5913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
59145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vanilla SSL to the server
59155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider server(ASYNC, OK);
5916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
59175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
59195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
5921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
59225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
59245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
59275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
59325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
59335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
59345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
59355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
59365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
59375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
59395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
5940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
59415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
59425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
59435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() != NULL);
59445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
59455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
59475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
59495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
59505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
59535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
59545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
59565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
59575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
59595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
59605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
59615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
59625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
59645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
59655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
59672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
59682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
59692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
59702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
59715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
59725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
59735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy can push a resource from an
59765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// origin that is different from that of its associated resource.
59777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
59785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo push_request;
59805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
59835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.method = "GET";
59845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.url = GURL("http://www.another-origin.com/foo.dat");
59855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
5987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
59882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
59895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
5990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
59915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
5993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
59945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
59965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
599790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
599890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
59995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
600190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
60025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
60057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
60065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
60087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
60095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
60117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
60125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
60135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
60145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
60155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "http://www.another-origin.com/foo.dat"));
6016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char kPushedData[] = "pushed";
6017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> stream2_body(
6018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(
6019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          2, kPushedData, strlen(kPushedData), true));
60205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
60225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
60235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
60245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 4, ASYNC),
6025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockRead(*stream2_body, 5, ASYNC),
60265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
60275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
60305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
60315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
60335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
60345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
60357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
60375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
60405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
60415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
60425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
60435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
60455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
60465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
60475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> push_trans(
6049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = push_trans->Start(&push_request, callback.callback(), log.bound());
60515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
60525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
60545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
60555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
60565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
60585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
60595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
60615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
60625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
60645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
60655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
60665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
60675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
60692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
60702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
60712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
60722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the pushed stream.
6074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(push_response->headers.get() != NULL);
60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, push_response->headers->response_code());
60765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(push_trans.get(), &response_data);
60785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
60795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("pushed", response_data);
60805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo push_load_timing_info;
60822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
60832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(push_load_timing_info);
60842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transactions should share a socket ID, despite being for different
60852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // origins.
60862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id,
60872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            push_load_timing_info.socket_log_id);
60882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
60905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_trans.reset();
60915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
60925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
60957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
60965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
60975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
60995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
61005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
61035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
61045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
61065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
61095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
61115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
611290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
611390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
61145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> push_rst(
611690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
61175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
61195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
61205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*push_rst, 4),
61215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
61247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
61255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
61277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
61285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
61307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
61315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
61325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
61335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
61345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "https://www.another-origin.com/foo.dat"));
61355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
61375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
61385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
61395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 5, ASYNC),
61405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
61415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
61445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
61455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
61475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
61485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
61497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
61515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
61545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
61555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
61565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
61575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
61595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
61615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
61635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
61645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
61665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
61675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
61695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
61705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
61725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
61745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
61755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through an
61785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTPS proxy
61797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
61815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
61825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
61845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
61855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
61865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
61875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL from a server with a bad cert
61895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite bad_cert_writes[] = {
61905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
61915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
61925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
61935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead bad_cert_reads[] = {
61965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
61975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
61985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL with a good cert
62015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite good_data_writes[] = {
62025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
62035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
62045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
62055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
62065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
62075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
62085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead good_cert_reads[] = {
62115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
62135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
62145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
62155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
62165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
62195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_reads, arraysize(bad_cert_reads),
62205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_writes, arraysize(bad_cert_writes));
62215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
62225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                good_data_writes, arraysize(good_data_writes));
62235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
62245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
62255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then valid SSL certificate
6232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
62355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
62392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
62415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
62435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
62475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
62495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
62535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
62555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
62585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
62615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
62645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
62655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
62665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
62682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
62705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
62725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
62735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
62745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
62765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
62795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
62805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
62815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
62825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
62835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
62845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
62875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
62895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
62915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
62935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
62975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
63005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
63035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
63045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
63055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
63075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
63105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
63125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
63135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
63145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
63155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
63165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
63185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return an error, so the transaction stops here (this test isn't
63195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // interested in the rest).
63205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
63215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
63225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
63235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
63265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
63285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
63305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
63325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
63365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
63395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
63425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
63435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
63445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "http://the.previous.site.com/");
63455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
63495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
63515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
63525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
63535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
63545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Referer: http://the.previous.site.com/\r\n\r\n"),
63555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
63585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
63595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
63605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
63615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
63625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
63635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
63665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
63685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
63705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
63725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
63765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
63795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
63815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
63825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
63865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
63885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST / HTTP/1.1\r\n"
63895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
63905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
63915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
63925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
63955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
63965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
63975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
63985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
63995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
64005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
64035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
64055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
64075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
64095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
64125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
64145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
64175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "PUT";
64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
64212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
64235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
64255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("PUT / HTTP/1.1\r\n"
64265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
64275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
64285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
64295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
64325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
64335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
64345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
64355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
64365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
64375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
64405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
64425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
64445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
64465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
64495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
64515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
64535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
64545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
64555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
64565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
64582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
64605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
64625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
64635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
64645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
64655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
64665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
64695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
64705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
64715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
64725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
64735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
64745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
64775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
64795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
64815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
64835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
64865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
64885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
64905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
64915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
64925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
64935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_BYPASS_CACHE;
64945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
64962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
64985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
65005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
65015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
65025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
65035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Pragma: no-cache\r\n"
65045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: no-cache\r\n\r\n"),
65055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
65085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
65095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
65105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
65115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
65125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
65135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
65165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
65185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
65225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
65295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       BuildRequest_CacheControlValidateCache) {
65305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
65315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
65335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_VALIDATE_CACHE;
65345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
65362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
65385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
65405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
65415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
65425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
65435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: max-age=0\r\n\r\n"),
65445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
65475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
65485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
65495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
65505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
65515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
65525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
65555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
65575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
65615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
65685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
65695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
65715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FooHeader", "Bar");
65725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
65742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
65765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
65785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
65795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
65805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
65815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FooHeader: Bar\r\n\r\n"),
65825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
65855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
65865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
65875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
65885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
65895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
65905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
65935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
65955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
65995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
66025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
66065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
66075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
66085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
66095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("referer", "www.foo.com");
66105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("hEllo", "Kitty");
66115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FoO", "bar");
66125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
66142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
66165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
66185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
66195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
66205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
66215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "referer: www.foo.com\r\n"
66225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "hEllo: Kitty\r\n"
66235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FoO: bar\r\n\r\n"),
66245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
66275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
66285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
66295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
66305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
66315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
66325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
66355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
66375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
66415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
66445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
66485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
66495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
66505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
66515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
66525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
66542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
66552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
66575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
66592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
66615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
66635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
66645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
66665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
66675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
66685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
66695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
66705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
66735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
66745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
66755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
66765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
66775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
66785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
66815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
66835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
66875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
66905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
66935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
66945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
66962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
66972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
66982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
66992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
67015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
67025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
67045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
67075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
67095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
67105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
67115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
67132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
67142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
67165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
67205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
67225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
67235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
67255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
67265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(write_buffer)),
67275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
67305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
67335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
67345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(read_buffer)),
67355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
67365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
67375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
67385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
67395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
67425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
67445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
6746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
67472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
67492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
67512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
67542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
67552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
67572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
67582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
67592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
67602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
67622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
67632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_text;
67652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
67662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
67672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("Payload", response_text);
67682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
67692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
67712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request;
67722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.method = "GET";
67732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.url = GURL("http://www.google.com/");
67742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.load_flags = 0;
67752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
67772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("socks4://myproxy:1080"));
67782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
67802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
67842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
67862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
67872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes[] = {
67892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
67902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
67922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
67932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
67942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
67962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
67972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
67982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
67992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Payload"),
68002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
68012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
68022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                data_writes, arraysize(data_writes));
6805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
68165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
68175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
68192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
68202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
68212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
68222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
68245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
68255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
68275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
68305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
68345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
68362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
68372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
68395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
68435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
68455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
68465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkRequest[] = {
68475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
68485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
68495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
68505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
68515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
68525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
68535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
68545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x50,  // 16-bit port (80)
68555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
68575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
68585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
68615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
68625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
68655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
68695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
68705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
68725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
68735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
68745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
68895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
68905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
68922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
68932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
68942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
68952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
68975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
68985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
69005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
69035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
69055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
69065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
69075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
69092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
69102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
69125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
6915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
69165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
69185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
69195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kSOCKS5OkRequest[] = {
69205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
69215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
69225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
69235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
69245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
69255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
69265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
69275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0xBB,  // 16-bit port (443)
69285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
69315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
69325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
69355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
69365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(kSOCKS5OkRequest)),
69375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
69385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
69405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
69445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
69455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
69475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
69485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
69495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
6956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
69575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
69675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
69685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
69702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
69712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
69722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
69732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
69755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
69765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
69785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
69815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that for connection endpoints the group names are correctly set.
69835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GroupNameTest {
69855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string proxy_server;
69865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
69875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_group_name;
69885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ssl;
69895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
69905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
6992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NextProto next_proto,
6993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps_) {
6994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
69955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6996ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
69975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
69985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
69995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair("host.with.alternate", 80), 443,
7000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(next_proto));
70015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session;
70035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GroupNameTransactionHelper(
70065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url,
70075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpNetworkSession>& session) {
70085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL(url);
70115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
70125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
70155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do not complete this request, the dtor will clean the transaction up.
70195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return trans->Start(&request, callback.callback(), BoundNetLog());
70205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
70235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
70255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
70265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
70275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
70285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/direct",
70295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
70305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
70315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
70325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
70335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
70345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://[2001:1418:13:1::25]/direct",
70355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[2001:1418:13:1::25]:80",
70365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
70375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
70385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
70405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
70415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
70425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/direct_ssl",
70435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
70445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
70455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
70465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
70475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
70485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://[2001:1418:13:1::25]/direct",
70495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/[2001:1418:13:1::25]:443",
70505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
70515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
70525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
70535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
70545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
70555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
70565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
70575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
70585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
70615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
70645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
70655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
70675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
70695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameTransportSocketPool* transport_conn_pool =
70705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameTransportSocketPool(NULL, NULL);
70715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
70725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
70735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockClientSocketPoolManager* mock_pool_manager =
70745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockClientSocketPoolManager;
70755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
70765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
70775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    peer.SetClientSocketPoolManager(mock_pool_manager);
70785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
70805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
70815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
70825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
70835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
70845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
70855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
70865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                transport_conn_pool->last_group_name_received());
70875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
70885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
70925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
70935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
70945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
70955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/http_proxy_normal",
70965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
70975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
70985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
70995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
71015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
71025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
71035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/http_connect_ssl",
71045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
71055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
71065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
71075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
71095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
71105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
71115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
71125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
71135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
71142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
71162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http_proxy",
71172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp://ftp.google.com/http_proxy_normal",
71182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp/ftp.google.com:21",
71192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      false,
71202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    },
71215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
71245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
71275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
71285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
71305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
71325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("http_proxy", 80);
71345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
71355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
71365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
71375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
71385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockClientSocketPoolManager* mock_pool_manager =
71405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockClientSocketPoolManager;
71415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
71425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
71435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    peer.SetClientSocketPoolManager(mock_pool_manager);
71445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
71465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
71475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
71485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
71495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
71505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
71515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
71525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                http_proxy_pool->last_group_name_received());
71535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
71545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
71575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
71585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
71595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
71605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks4_direct",
71615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/www.google.com:80",
71625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
71635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
71645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
71655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
71665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks5_direct",
71675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/www.google.com:80",
71685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
71695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
71705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
71725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
71735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
71745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks4_ssl",
71755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/www.google.com:443",
71765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
71775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
71785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
71795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
71805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks5_ssl",
71815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/ssl/www.google.com:443",
71825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
71835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
71845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
71865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
71875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
71885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/host.with.alternate:443",
71895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
71905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
71915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
71945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
71975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
71985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
72005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
72025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("socks_proxy", 1080);
72045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
72055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
72065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
72075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
72085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockClientSocketPoolManager* mock_pool_manager =
72105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockClientSocketPoolManager;
72115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
72125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
72135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    peer.SetClientSocketPoolManager(mock_pool_manager);
72145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
7216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
72175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
72195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
72205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
72215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
72225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
72235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
72245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
72255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                socks_conn_pool->last_group_name_received());
72265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
72275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
72305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
72315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
72325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
72335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
72355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("myproxy:70;foobar:80"));
72365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This simulates failure resolving all hostnames; that means we will fail
72385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connecting to both proxies (myproxy:70 and foobar:80).
7239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
72405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
72422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
72445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
72465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
72515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
72525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base test to make sure that when the load flags for a request specify to
72555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bypass the cache, the DNS cache is not used.
72567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int load_flags) {
72585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a request, asking to bypass the cache(s).
72595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
72605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
72615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = load_flags;
72625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
72635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Select a host resolver that does caching.
7265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver);
72665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
7268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateSession(&session_deps_)));
72695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Warm up the host cache so it has an entry for "www.google.com".
72715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist;
72725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
7273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int rv = session_deps_.host_resolver->Resolve(
72745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
72755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.callback(), NULL, BoundNetLog());
72765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
72785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that it was added to host cache, by doing a subsequent async lookup
72815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and confirming it completes synchronously.
7282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(
72835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
72845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.callback(), NULL, BoundNetLog());
72855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, rv);
72865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject a failure the next time that "www.google.com" is resolved. This way
72885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can tell if the next lookup hit the cache, or the "network".
72895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (cache --> success, "network" --> failure).
7290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
72915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
72935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first read -- this won't be reached as the host resolution will fail first.
72945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
72955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the request.
72995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
73005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, rv);
73015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
73025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we bypassed the cache, we would have gotten a failure while resolving
73045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "www.google.com".
73055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
73065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are multiple load flags that should trigger the host cache bypass.
73095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test each in isolation:
73107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
73115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
73125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
73155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
73165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
73195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
73205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure we can handle an error when writing the request.
73237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
7324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
73275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
73285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
73295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
73305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure[] = {
73325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, ERR_CONNECTION_RESET),
73335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(NULL, 0,
73355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                write_failure, arraysize(write_failure));
7336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
73375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
73395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
73435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
73455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
73465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
73485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
73495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that a connection closed after the start of the headers finishes ok.
73527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
7353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
73565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
73575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
73585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
73595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
73615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1."),
73625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
73635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
73675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
73695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
73735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
73755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
73765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
73785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
73815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
73825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
73845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
73855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
73875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
73885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
73905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that a dropped connection while draining the body for auth
73935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// restart does the right thing.
73947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
7395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
73985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
73995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
74005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
74015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
74035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
74045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
74055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
74065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
74095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
74105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
74115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
74125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
74135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauth"),
74145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
74155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
74185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
7419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
74205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
74225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
74235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
74245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
74255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
74265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
74275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
74285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
74315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
74325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
74335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
74345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
74355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
74365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
74395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
7440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
74415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
74435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
74465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
74485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
74495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
74515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
74545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
74555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
74565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
74585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
74605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
74615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
74625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
74645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
74675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
74685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
74695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
74705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
74715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections going through a proxy that sends extra data.
74737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
7474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
74755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
74775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
74785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
74795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
74805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
74825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
74835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
74845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
74875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
74885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
7490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
74915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
74935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->ResetNextMockIndexes();
74955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
74972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
74995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
75015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
75025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
75045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
75055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
75085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
75095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
75105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
75115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
75125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
75142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
75165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
75185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
75195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
75205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
75215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
75245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
75265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
75285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
75295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
75315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
75335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
75345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
75365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
75375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
75395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
75405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
75415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
75442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file_path;
75452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
75462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 kFakeSize = 100000;  // file is actually blank
75472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileElementReader::ScopedOverridingContentLengthForTests
75482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overriding_content_length(kFakeSize);
75492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
75512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
75527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
75537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file_path,
75547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
75557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
75567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
75572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadDataStream upload_data_stream(&element_readers, 0);
75582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
75605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
75615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
75622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
75635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
75645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
75662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
75685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
75705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
75715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
75725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
75735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
75745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
75765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
75785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
75805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
75815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
75835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
75845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
75865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
75875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
75895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
75905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
75925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
75935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
75945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
75955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file_path, false);
75975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
76002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file;
76012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
76022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string temp_file_content("Unreadable file.");
76032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
76042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   temp_file_content.length()));
76052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
76062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
76082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
76097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
76107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file,
76117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
76127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
76137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
76142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadDataStream upload_data_stream(&element_readers, 0);
76152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
76175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
76185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
76192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
76205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
76215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we try to upload an unreadable file, the network stack should report
76235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the file size as zero and upload zero bytes for that file.
76245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
76252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
76275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
76295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
76305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
76315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
76335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST /upload HTTP/1.1\r\n"
76345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
76355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
76365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
76375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, OK),
76385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
76405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                arraysize(data_writes));
7641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
76425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
76445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
76465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
76475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
76495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
76505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
76525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
7653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
76545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
76555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file, false);
76575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
76602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file;
76615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
76625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string temp_file_contents("Unreadable file.");
76635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string unreadable_contents(temp_file_contents.length(), '\0');
76645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
76655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   temp_file_contents.length()));
76665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
76682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
76697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
76707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file,
76717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
76727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
76737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
76742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadDataStream upload_data_stream(&element_readers, 0);
76752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request;
76772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.method = "POST";
76782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
76792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
76802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.load_flags = 0;
76812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
76832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
76855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
76875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
76885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
76895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
76905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
76925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
76935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
76945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
76965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST /upload HTTP/1.1\r\n"
76975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
76985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
76995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 16\r\n\r\n"),
77005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
77015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST /upload HTTP/1.1\r\n"
77035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
77045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
77055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n"
77065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
77075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
77085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              temp_file_contents.length()),
77095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, OK),
77105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
77125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                arraysize(data_writes));
7713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
77145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
77165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
77185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
77215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
77225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
77245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
7725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
77265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
77275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
77285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make the file unreadable and try again.
77305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
77315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
77335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
77355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
77365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
77395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
77405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
77425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
7743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
77445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
77455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
77465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file, false);
77485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that changes to Auth realms are treated like auth rejections.
77517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
77525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
77545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
77555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
77565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
77575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First transaction will request a resource and receive a Basic challenge
77595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with realm="first_realm".
77605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
77615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
77625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
77635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
77645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
77655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
77675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
77685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
77695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
77705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), provide an Authentication header
77735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for first_realm. The server will reject and provide a challenge with
77745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // second_realm.
77755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
77765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
77775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
77785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
77795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmF6\r\n"
77805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
77815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
77835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
77845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
77855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
77865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This again fails, and goes back to first_realm. Make sure that the
77895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry is removed from cache.
77905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
77915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
77925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
77935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
77945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
77955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
77965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
77985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
77995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
78005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
78015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try one last time (with the correct password) and get the resource.
78045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes4[] = {
78055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
78065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
78075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
78085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmFy\r\n"
78095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
78105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads4[] = {
78125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
78135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html; charset=iso-8859-1\r\n"
78145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n"
78155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"
78165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
78175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
78205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
78215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
78225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
78235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
78245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
78255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
78265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes4, arraysize(data_writes4));
7827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
7828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
7829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
7830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
78315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
78335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
7836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
78375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the first request with Authorize headers. There should be a
78395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for first_realm waiting to be filled in after the
78405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
78415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
78425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
78445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
78465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
78475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AuthChallengeInfo* challenge = response->auth_challenge.get();
78485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
78495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
78505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
78515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
78525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
78535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the second request with an incorrect password. There should be a
78555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for second_realm waiting to be filled in after the
78565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
78575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
78585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
78595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBaz), callback2.callback());
78605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
78625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
78645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
78655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
78665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
78675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
78685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
78695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("second_realm", challenge->realm);
78705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
78715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the third request with another incorrect password. There should be
78735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a password prompt for first_realm waiting to be filled in. If the password
78745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prompt is not present, it indicates that the HttpAuthCacheEntry for
78755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first_realm was not correctly removed.
78765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
78775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
78785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kSecond, kFou), callback3.callback());
78795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
78815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
78835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
78845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
78855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
78865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
78875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
78885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
78895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
78905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the fourth request with the correct password and username.
78925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
78935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
78945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBar), callback4.callback());
78955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
78975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
78995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
79005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
79015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
79045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
79055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
79065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
7908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
7909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
79105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
79115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
79135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
79145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
79155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
79205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
79235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
79255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
79275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
79315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
79335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair http_host_port_pair("www.google.com", 80);
79365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpServerProperties& http_server_properties =
79375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *session->http_server_properties();
79385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
79395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.HasAlternateProtocol(http_host_port_pair));
79405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
79425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
79445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
7945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
79465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
79475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
79485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
79495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
79515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
79525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
79535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
79555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PortAlternateProtocolPair alternate =
79565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.GetAlternateProtocol(http_host_port_pair);
79575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PortAlternateProtocolPair expected_alternate;
79585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_alternate.port = 443;
7959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
79605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(expected_alternate.Equals(alternate));
79615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
79645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MarkBrokenAlternateProtocolAndFallback) {
79655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
79665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
79705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
79735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
79745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
7975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
79765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
79785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
79795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
79805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
79815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
79835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
7984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
79855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7988ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
79895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
79905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Port must be < 1024, or the header will be ignored (since initial port was
79915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // port 80 (another restricted port).
79925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
79935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
79945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      666 /* port is ignored by MockConnect anyway */,
7995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
79965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
79995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
80025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
80045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
80065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
80085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
80095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
80115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
80125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
80135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
80155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url)));
80165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PortAlternateProtocolPair alternate =
80175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties->GetAlternateProtocol(
80185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HostPortPair::FromURL(request.url));
80195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
80205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
80235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedBlocked) {
80245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
80255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
80265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
80275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
80285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
80295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
80315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
80325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
80335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
80345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
80365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
80375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
80395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
80415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
80425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
80435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
80445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
80465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
80485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8051ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
80525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
80535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
80545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
80555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
80565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
80585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8060868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
80615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
80642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
80652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
80665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid change to unrestricted port should fail.
80685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
80692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
80705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
80722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       AlternateProtocolPortRestrictedPermitted) {
80732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure that we're allowed to redirect traffic via an alternate
80742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
80752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a restricted port (port < 1024) if we set
80762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enable_user_alternate_protocol_ports.
80772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
8079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.enable_user_alternate_protocol_ports = true;
80802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo restricted_port_request;
80822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.method = "GET";
80832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
80842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.load_flags = 0;
80852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
80872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider first_data;
80882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first_data.set_connect_data(mock_connect);
8089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
80902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
80922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
80932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("hello world"),
80942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, OK),
80952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
80962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider second_data(
80972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
80992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
81032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session->http_server_properties();
81042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
81052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  http_server_properties->SetAlternateProtocol(
81062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
81072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kUnrestrictedAlternatePort,
8108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
81092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
81122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
81132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Start(
81152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
81162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog()));
81172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change to unrestricted port should succeed.
81182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
81195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
81225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedAllowed) {
81235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
81245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
81255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
81265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
81275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
81285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
81305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
81315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
81325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
81335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
81355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
81365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
81385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
81405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
81415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
81425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
81435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
81445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
81455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
81475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
81515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
81525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
81535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
81545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
81555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
81575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
81605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
81632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
81642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
81655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
81675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
81685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
81715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed1) {
81725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
81735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
81745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
81755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
81765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
81775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
81795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
81805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
81815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_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)  const int kRestrictedAlternatePort = 80;
82025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
82035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
82045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
82065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
82095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
82105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
82125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
82135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
82145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
82155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
82165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
82175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
82195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed2) {
82205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
82215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
82225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
82235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
82245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
82255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
82275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
82285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
82295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
82305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
82325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
82335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
82355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
82375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
82385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
82395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
82405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
82425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
82445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
82465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
82485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
82495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
82505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
82515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
82525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
82545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
82575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
82585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
82605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
82615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
82625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to an unrestricted port should pass.
82635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
82645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
82655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
82675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolUnsafeBlocked) {
82685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
82695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unsafe port, and that we resume the second
82705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
82715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
82725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
82745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
82755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
82765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
82775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The alternate protocol request will error out before we attempt to connect,
82795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so only the standard HTTP request will try to connect.
82805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
82815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
82825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
82835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
82845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(
82865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
82885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
82905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
82925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
82935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnsafePort = 7;
82945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
82955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
82965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnsafePort,
8297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
82985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
83015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
83025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
83045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The HTTP request should succeed.
83065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
83075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable alternate protocol before the asserts.
83095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(false);
83105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
83125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
83145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
83155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
83175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
83185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
83195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
83205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
83225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
83235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
83245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
83265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
83275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
83285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
83295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
83335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
83345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
83365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
83375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
83385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK)
83395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
83425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
83445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
83467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
83485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
834990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
835090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
83515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
83525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
83547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
83555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
83565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
83575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
83585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
83595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
83625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
83635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
83645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
83665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
83685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
83695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
83705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
83715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
83735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
83745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
83765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
83782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
83805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
83825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
83845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
83865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
83885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
83895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
83915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
83925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
83935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
83955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
83975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
83995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
84015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
84035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
84045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
84055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
84065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
84085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
84095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
84125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
84135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
84145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
84165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
84175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
84185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
84195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
84235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
84265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
84285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
84295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
84325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
84335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
84355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
84375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_socket(
84385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
84395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_socket.set_connect_data(never_finishing_connect);
84405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 2 and 3 are the hanging Alternate-Protocol and
84415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-Alternate-Protocol jobs from the 2nd transaction.
8442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
84445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
84467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
84485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
844990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
845090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
845190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
845290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
84535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
84545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1),
84555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
84565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
84587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
84597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
84607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
84615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
84625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1),
84635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data1),
84645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2),
84655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data2),
84665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
84675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
84705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2,  // wait for writes to finish before reading.
84715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
84725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
84735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 4 is the successful Alternate-Protocol for transaction 3.
8474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
84755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
84785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
8481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
84825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
84845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
84865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
84885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
84905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
84915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
84935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
84945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
84955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
8497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
84985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
84995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
8502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
85035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
85045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
85075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
85085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
85105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
85135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
85145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
85155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
85165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
85175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans3.GetResponseInfo();
85195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
85225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
85235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
85245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
85255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
85265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
85275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
85295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
85305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
85315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
85335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
85345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
85355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
85365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
85405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
85415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
85435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
85445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
85455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
85465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
85475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
85495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
85515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
85537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
85555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
85575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_alternate_protocol_socket(
85585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
85595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_alternate_protocol_socket.set_connect_data(
85605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
85625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_alternate_protocol_socket);
85635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2nd request is just a copy of the first one, over HTTP again.
8565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
85665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
85685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
85745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
85765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
85785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
85815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
85835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
85845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
85855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
85895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
85915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
85935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
85965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
85975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
85985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
86005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
86015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CapturingProxyResolver : public ProxyResolver {
86045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
86055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
86065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CapturingProxyResolver() {}
86075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetProxyForURL(const GURL& url,
86095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ProxyInfo* results,
86105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const CompletionCallback& callback,
86115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RequestHandle* request,
86122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const BoundNetLog& net_log) OVERRIDE {
86135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
86145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HostPortPair("myproxy", 80));
86155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->UseProxyServer(proxy_server);
86165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resolved_.push_back(url);
86175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
86185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
86195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelRequest(RequestHandle request) OVERRIDE {
86215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
86225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
86235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
86255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
86265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
86275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
86285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelSetPacScript() OVERRIDE {
86305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
86315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
86325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
86342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const CompletionCallback& /*callback*/) OVERRIDE {
86355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
86365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
86375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<GURL>& resolved() const { return resolved_; }
86395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
86415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> resolved_;
86425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
86445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
86455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
86475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForTunneledNpnSpdy) {
86485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
86495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
86505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
86525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_auto_detect(true);
86535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_pac_url(GURL("http://fooproxyurl"));
86545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
86565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
8657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
86585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
86595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
86602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
8661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
86625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
86645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
86655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
86665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
86675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
86715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
86745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
86765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
86805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
86825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
86847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
86865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
868790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
868890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
86895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
86905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
86915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
86925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
869390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*req),                              // 3
86945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
86975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
86997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
87005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
87015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
87025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 4),  // 2, 4
87035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 4),  // 5
87045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 4),  // 6
87055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
87085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
87095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
87115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
87135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
87145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
87155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
87165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
87185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
87195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
87275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
87315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
87335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
87345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
87355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
87365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
87385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
87395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
87405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
87445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
87485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
87505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
87515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
87525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
87535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
87555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
87565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
87575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://www.google.com/",
87585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[0].spec());
87595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https://www.google.com/",
87605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[1].spec());
87615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
87632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
87642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
87652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
87665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
87695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
87705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
87715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
87725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
87745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
87755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
87765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
87775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8779eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8780eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
87815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
87845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
87895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
87915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
87937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
87955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
879690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
879790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
87985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
87995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
88017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
88025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
88035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
88045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
88055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
88065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
88095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
88105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
88115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
88135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
88155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
88175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
88225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
88265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
88315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
88335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
88355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
883690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
883790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     kPrivacyModeDisabled);
8838ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
88397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateSecureSpdySession(session, key, BoundNetLog());
88405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
88445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
88485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
88525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
88535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
88565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
88575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GenerateAuthToken is a mighty big test.
88595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It tests all permutation of GenerateAuthToken behavior:
88605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Synchronous and Asynchronous completion.
88615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - OK or error on completion.
88625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Direct connection, non-authenticating proxy, and authenticating proxy.
88635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - HTTP or HTTPS backend (to include proxy tunneling).
88645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Non-authenticating and authenticating backend.
88655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
88665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In all, there are 44 reasonable permuations (for example, if there are
88675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// problems generating an auth token for an authenticating proxy, we don't
88685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to test all permutations of the backend server).
88695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
88705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test proceeds by going over each of the configuration cases, and
88715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// potentially running up to three rounds in each of the tests. The TestConfig
88725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifies both the configuration for the test as well as the expectations
88735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the results.
88747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
88755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kServer[] = "http://www.example.com";
88765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kSecureServer[] = "https://www.example.com";
88775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kProxy[] = "myproxy:70";
88785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
88795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum AuthTiming {
88815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_NONE,
88825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_SYNC,
88835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_ASYNC,
88845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
88875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
88885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
88895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
88905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxy(
88915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
88925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
88935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
88945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
88955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
88965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
88975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
88985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
88995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxyAuth(
89005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
89015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
89025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
89035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
89045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthThroughProxy(
89055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
89065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
89075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
89085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
89095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthWithProxyAuth(
89105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
89115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
89125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
89135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n"
89145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
89155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnect(
89165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
89175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
89185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
89195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnectProxyAuth(
89205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
89215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
89225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
89235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
89245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
89265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
89275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
89285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
89295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
89305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kFailure(
89315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Should not be called.");
89325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
89335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
89345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
89355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
89365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
89375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
89385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyChallenge(
89395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 407 Unauthorized\r\n"
89405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authenticate: Mock realm=proxy\r\n"
89415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: close\r\n"
89425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
89435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
89445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
89455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyConnected(
89465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 Connection Established\r\n\r\n");
89475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
89495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no constructors, but the C++ compiler on Windows warns about
89505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unspecified data in compound literals. So, moved to using constructors,
89515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and TestRound's created with the default constructor should not be used.
89525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestRound {
89535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound()
89545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : expected_rv(ERR_UNEXPECTED),
89555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
89565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
89575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
89585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
89595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg)
89605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
89615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
89625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
89635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
89645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
89655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
89665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
89675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg, const MockWrite* extra_write_arg,
89685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const MockRead* extra_read_arg)
89695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
89705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
89715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
89725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(extra_write_arg),
89735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(extra_read_arg) {
89745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
89755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite write;
89765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead read;
89775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_rv;
89785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* extra_write;
89795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* extra_read;
89805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNoSSL = 500;
89835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestConfig {
89855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* proxy_url;
89865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming proxy_auth_timing;
89875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int proxy_auth_rv;
89885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* server_url;
89895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming server_auth_timing;
89905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int server_auth_rv;
89915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_auth_rounds;
89925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int first_ssl_round;
89935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound rounds[3];
89945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } test_configs[] = {
89955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server with a direct connection.
89965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
89975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
89985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server with a direct connection.
89995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
90005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
90025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
90035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
90055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
90065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
90085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
90095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
90115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through a non-authenticating proxy.
90125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
90135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kSuccess, OK)}},
90145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through a non-authenticating proxy.
90155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
90165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
90175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
90185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
90195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
90205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
90215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
90225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
90235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
90245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
90255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
90265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
90275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through an authenticating proxy.
90285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
90295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
90315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
90325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
90345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
90355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
90375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
90385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
90405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through an authenticating proxy.
90415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
90425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
90455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
90465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
90495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
90505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
90535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
90545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
90575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
90585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
90615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
90625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
90655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
90665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
90695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
90705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
90715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
90725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
90735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a direct connection.
90745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
90755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
90765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server with a direct connection.
90775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
90785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
90805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
90815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
90835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
90845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
90865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
90875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
90885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
90895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a non-authenticating proxy.
90905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
90915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
90925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through a non-authenticating proxy.
90935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
90945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
90955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
90965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
90975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
90985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
90995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
91005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
91015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
91025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
91035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
91045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
91055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-Authenticating HTTPS server through an authenticating proxy.
91065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
91075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
91095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
91105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
91125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
91135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
91155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
91165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
91185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through an authenticating proxy.
91195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
91205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
91245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
91255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
91295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
91305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
91345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
91355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
91395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
91405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
91445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
91455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
91495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
91505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
91545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
91555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
91565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
91575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
91585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
91595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
91625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpAuthHandlerMock::Factory* auth_factory(
91635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new HttpAuthHandlerMock::Factory());
9164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.http_auth_handler_factory.reset(auth_factory);
91655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TestConfig& test_config = test_configs[i];
91665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up authentication handlers as necessary.
91685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_auth_timing != AUTH_NONE) {
91695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int n = 0; n < 2; n++) {
91705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
91715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string auth_challenge = "Mock realm=proxy";
91725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL origin(test_config.proxy_url);
91735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
91745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               auth_challenge.end());
91755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
91765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        origin, BoundNetLog());
91775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->SetGenerateExpectation(
91785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_timing == AUTH_ASYNC,
91795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_rv);
91805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
91815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
91825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
91835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.server_auth_timing != AUTH_NONE) {
91845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
91855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string auth_challenge = "Mock realm=server";
91865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL origin(test_config.server_url);
91875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
91885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             auth_challenge.end());
91895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
91905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      origin, BoundNetLog());
91915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->SetGenerateExpectation(
91925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_timing == AUTH_ASYNC,
91935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_rv);
91945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
91955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
91965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_url) {
9197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(
91985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ProxyService::CreateFixed(test_config.proxy_url));
91995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(ProxyService::CreateDirect());
92015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
92025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
92045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
92055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL(test_config.server_url);
92065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
92075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
92092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HttpNetworkTransaction trans(
9210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        DEFAULT_PRIORITY, CreateSession(&session_deps_));
92115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int round = 0; round < test_config.num_auth_rounds; ++round) {
92135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TestRound& read_write_round = test_config.rounds[round];
92145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Set up expected reads and writes.
92165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead reads[2];
92175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reads[0] = read_write_round.read;
92185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_reads = 1;
92195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_read) {
92205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reads[1] = *read_write_round.extra_read;
92215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_reads = 2;
92225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
92235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite writes[2];
92255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes[0] = read_write_round.write;
92265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_writes = 1;
92275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_write) {
92285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        writes[1] = *read_write_round.extra_write;
92295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_writes = 2;
92305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
92315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StaticSocketDataProvider data_provider(
92325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reads, length_reads, writes, length_writes);
9233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
92345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add an SSL sequence if necessary.
92365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
92375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round >= test_config.first_ssl_round)
9238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_deps_.socket_factory->AddSSLSocketDataProvider(
92395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &ssl_socket_data_provider);
92405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Start or restart the transaction.
92425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestCompletionCallback callback;
92435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int rv;
92445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round == 0) {
92455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.Start(&request, callback.callback(), BoundNetLog());
92465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
92475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.RestartWithAuth(
92485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AuthCredentials(kFoo, kBar), callback.callback());
92495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
92505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rv == ERR_IO_PENDING)
92515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = callback.WaitForResult();
92525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Compare results with expected data.
92545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(read_write_round.expected_rv, rv);
92555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpResponseInfo* response = trans.GetResponseInfo();
92565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.expected_rv == OK) {
92575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ASSERT_TRUE(response != NULL);
92585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
92595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response == NULL);
92605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(round + 1, test_config.num_auth_rounds);
92615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
92625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
92635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round + 1 < test_config.num_auth_rounds) {
92645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(response->auth_challenge.get() == NULL);
92655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
92665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response->auth_challenge.get() == NULL);
92675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
92685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
92695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
92705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
92715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
92735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do multi-round authentication and make sure it works correctly.
92745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock::Factory* auth_factory(
92755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerMock::Factory());
9276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(auth_factory);
9277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
92805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
92825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->set_connection_based(true);
92835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string auth_challenge = "Mock realm=server";
92845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin("http://www.example.com");
92855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
92865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         auth_challenge.end());
92875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
92885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  origin, BoundNetLog());
92895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
92905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = OK;
92925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = NULL;
92935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
92945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
92955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = origin;
92965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
92975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
92995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use a TCP Socket Pool with only one connection per group. This is used
93015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to validate that the TCP socket is not released to the pool between
93025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // each round of multi-round authentication.
93035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSessionPeer session_peer(session);
93045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
93055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
93065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,  // Max sockets for pool
93075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,   // Max sockets per group
93085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &transport_pool_histograms,
9309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.host_resolver.get(),
9310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory.get(),
9311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.net_log);
93125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockClientSocketPoolManager* mock_pool_manager =
93135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockClientSocketPoolManager;
93145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_pool_manager->SetTransportSocketPool(transport_pool);
93155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session_peer.SetClientSocketPoolManager(mock_pool_manager);
93165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
93195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
93205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
93225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
93255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
93265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
93295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
93305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
93325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
93335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
93345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
93355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
93365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
93375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
93385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
93395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
93405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
93415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
93425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
93445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
93455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
93465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
93475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
93485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
93495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
93505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
93515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
93525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing request
93535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
93545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
93565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
93575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
93585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
93595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
93605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
93615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
93625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
93635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
93645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing response
93655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
93665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_provider(reads, arraysize(reads),
93685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         writes, arraysize(writes));
9369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
93705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kSocketGroup = "www.example.com:80";
93725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round of authentication.
93745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
93755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
93765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
93775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
93785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
93795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
93805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
93815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->auth_challenge.get() == NULL);
93825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
93835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In between rounds, another request comes in for the same domain.
93855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should not be able to grab the TCP socket that trans has already
93865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // claimed.
93875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans_compete(
9388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
93895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_compete;
93905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_compete->Start(
93915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &request, callback_compete.callback(), BoundNetLog());
93925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
93935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback_compete.WaitForResult at this point would stall forever,
93945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since the HttpNetworkTransaction does not release the request back to
93955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool until after authentication completes.
93965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round of authentication.
93985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
93995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
94005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
94015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
94025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
94035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
94045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
94055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
94065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
94075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Third round of authentication.
94095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
94105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
94115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
94125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
94135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
94145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
94155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
94165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
94175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
94185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fourth round of authentication, which completes successfully.
94205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
94215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
94225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
94235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
94245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
94255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
94265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
94275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
94285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
94295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the body since the fourth round was successful. This will also
94315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // release the socket back to the pool.
94325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
94345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
94355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
94365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
94385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
94395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are still 0 idle sockets, since the trans_compete transaction
94405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be handed it immediately after trans releases it to the group.
94415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
94425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The competing request can now finish. Wait for the headers and then
94445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read the body.
94455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_compete.WaitForResult();
94465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
94485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
94495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
94505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
94525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
94535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, the socket is released to the group.
94555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
94565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
94575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests the case that a request is issued via http instead of spdy after
94595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// npn is negotiated.
94607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
94615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
9462ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::vector<NextProto> next_protos;
9463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  next_protos.push_back(kProtoHTTP11);
9464ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  HttpStreamFactory::SetNextProtos(next_protos);
94655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
94665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
94675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
94685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
94695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
94715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
94725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
94735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
94745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
94755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
94795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
94805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
94825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
94835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
94845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
94855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
94875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
94885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto = "http/1.1";
94895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.protocol_negotiated = kProtoHTTP11;
94905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
94925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
94945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
9495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
94965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
94985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
95002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
95025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
95045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
95065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
95075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
95095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
95115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
95125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
95145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
95155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
95165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
95185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
95195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
95205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
95225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the SSL handshake completing with an NPN negotiation
95235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // followed by an immediate server closing of the socket.
95245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fix crash:  http://crbug.com/46369
95255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
95265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
95275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
95295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
95305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
95315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
95325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
95347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
95365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
953790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
953890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
95395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
95405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
95425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
95435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
95445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
95465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,  // don't wait in this case, immediate hangup.
95475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
95485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
95505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
95525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
95542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
95565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
95585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
95595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
95605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
95615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9562ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A subclass of HttpAuthHandlerMock that records the request URL when
9563ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// it gets it. This is needed since the auth handler may get destroyed
9564ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// before we get a chance to query it.
9565ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9566ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public:
9567ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9568ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
9569ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual ~UrlRecordingHttpAuthHandlerMock() {}
9570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
9571ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch protected:
9572ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9573ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const HttpRequestInfo* request,
9574ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const CompletionCallback& callback,
9575ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    std::string* auth_token) OVERRIDE {
9576ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *url_ = request->url;
9577ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        credentials, request, callback, auth_token);
9579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
9580ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
9581ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private:
9582ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL* url_;
9583ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
9584ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
95857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
95865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test ensures that the URL passed into the proxy is upgraded
95875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to https when doing an Alternate Protocol upgrade.
95885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
9589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
95905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
95922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
95932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
9594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
9595ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL request_url;
9596ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
9597ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    HttpAuthHandlerMock::Factory* auth_factory =
9598ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new HttpAuthHandlerMock::Factory();
9599ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UrlRecordingHttpAuthHandlerMock* auth_handler =
9600ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new UrlRecordingHttpAuthHandlerMock(&request_url);
9601ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9602ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->set_do_init_from_challenge(true);
9603ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    session_deps_.http_auth_handler_factory.reset(auth_factory);
9604ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
96055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
96075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
96085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com");
96095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
96105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round goes unauthenticated through the proxy.
96125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_1[] = {
96135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
96145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
96155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
96165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
96175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_1[] = {
96195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
96205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
96215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Alternate-Protocol: 443:npn-spdy/2\r\n"
96225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Proxy-Connection: close\r\n"
96235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
96245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
96265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  data_writes_1, arraysize(data_writes_1));
96275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round tries to tunnel to www.google.com due to the
96295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Alternate-Protocol announcement in the first round. It fails due
96305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a proxy authentication challenge.
96315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the failure, a tunnel is established to www.google.com using
96325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Proxy-Authorization headers. There is then a SPDY request round.
96335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
96345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Despite the "Proxy-Connection: Close", these are done on the
96355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
96365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // does a Disconnect and Connect on the same socket, rather than trying
96375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to obtain a new one.
96385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
96395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Originally, the proxy response to the second CONNECT request
96405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simply returned another 407 so the unit test could skip the SSL connection
96415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // establishment and SPDY framing issues. Alas, the
96425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // retry-http-when-alternate-protocol fails logic kicks in, which was more
96435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complicated to set up expectations for than the SPDY session.
96445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
964590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
964690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
96477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
96487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
96495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_2[] = {
96515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt without Proxy-Authorization.
96525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
96535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
96545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
96555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
96565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt with Proxy-Authorization.
96585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
96595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
96605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
96615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: auth_token\r\n"
96625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
96635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY request
96655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
96665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
96685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Authenticate: Mock\r\n"
96695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Connection: close\r\n"
96705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "\r\n");
96715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
96725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_2[] = {
96735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt fails
96745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
96755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kRejectConnectResponse,
96765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kRejectConnectResponse) - 1, 1),
96775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt passes
96795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kAcceptConnectResponse,
96805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kAcceptConnectResponse) -1, 4),
96815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY response
96835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 6),
96845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 6),
96855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 6),
96865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_2(
96885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads_2, arraysize(data_reads_2),
96895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes_2, arraysize(data_writes_2));
96905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
96927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
96935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
96955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
96965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
96975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
96985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
96995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
97045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
9705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round should work and provide the Alternate-Protocol state.
97085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_1;
97092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_1(
9710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
97115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
97125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
97135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_1.WaitForResult());
97145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round should attempt a tunnel connect and get an auth challenge.
97165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_2;
97172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_2(
9718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
97195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
97205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
97215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_2.WaitForResult());
97225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans_2->GetResponseInfo();
97235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
97245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response->auth_challenge.get() == NULL);
97255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart with auth. Tunnel should work and response received.
97275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_3;
97285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->RestartWithAuth(
97295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback_3.callback());
97305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
97315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_3.WaitForResult());
97325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After all that work, these two lines (or actually, just the scheme) are
97345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // what this test is all about. Make sure it happens correctly.
97355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https", request_url.scheme());
97365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com", request_url.host());
97375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
97392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
97402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
97412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
97425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
97435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we cancel the transaction as the connection is completing, that
97455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything tears down correctly.
97467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
97475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup everything about the connection to complete synchronously, so that
97485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after calling HttpNetworkTransaction::Start, the only thing we're waiting
97495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for is the callback from the HttpStreamRequest.
97505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then cancel the transaction.
97515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that we don't crash.
97525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(SYNCHRONOUS, OK);
97535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
97545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
97555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello world"),
97565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
97575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
97585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
97605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
97615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
97625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
97635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
97655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
97662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY,
9767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 CreateSession(&session_deps_)));
97685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
97705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.set_connect_data(mock_connect);
9771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
97725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
97745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
97765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
97775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
97785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();  // Cancel the transaction here.
97795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
978090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
97815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
97825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic GET request through a proxy.
97847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyGet) {
9785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
97862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
97875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
9788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
9789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
97925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
97935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
97945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
97965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
97975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
97985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
97995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
98025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
98035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
98045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
98055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
98065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
98095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
9810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
98115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
98135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
98165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
98185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
98195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
98215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
98245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
98275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
98285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
98295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
98305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
98312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
98322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
98332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
98342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
98352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
98365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
98375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy.
98397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
9840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
98412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
98425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
9843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
9844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
98455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
98475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
98485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
98495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
98515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
98525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
98535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
98545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
98555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
98575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
98585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
98595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
98625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
98635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
98655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
98665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
98675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
98685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
98715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
9872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
98735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
9874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
98755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
98775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
98805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
98825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
98835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
98855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
98875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
98885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
98895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
98905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
98915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
98925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
98935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
98945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
98955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
98975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
99005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
99015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
99025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
99035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
99042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
99052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
99062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
99072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
99082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
99095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy, but the server hangs up
99125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while establishing the tunnel.
99137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
9914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
99155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
9916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
9917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
99185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
99205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
99215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
99225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
99245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
99255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
99265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
99275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
99285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
99305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
99315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
99325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
99355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
99365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
99375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
99385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
99415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
9942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
99435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
9944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
99455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
99475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
99505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
99525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
99535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
99555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
99565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
99575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
99585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
99595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
99605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
99615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
99625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
99635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
99645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
99655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for crbug.com/55424.
99687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
996990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
997090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
99715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
99725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
99747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
99755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
99765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
99775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
99785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
99795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
99825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
99835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
99845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
99865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
99887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
99905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
99925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
99945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
999590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
999690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     kPrivacyModeDisabled);
9997ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
99987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateInsecureSpdySession(session, key, BoundNetLog());
99995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
100015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
100025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
100035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
100045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the important line that marks this as a preconnect.
100065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
100075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
100105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestCompletionCallback callback;
100125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
100135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
100155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given a net error, cause that error to be returned from the first Write()
100185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call and verify that the HttpTransaction fails with that error.
100197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int error, IoMode mode) {
100215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
100225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
100235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
100245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
100255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data(mode, OK);
100275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockWrite data_writes[] = {
100285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockWrite(mode, error),
100295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data(NULL, 0,
100315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     data_writes, arraysize(data_writes));
10032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
100345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
100362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
100385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
100405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
100415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == net::ERR_IO_PENDING)
100425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
100435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(error, rv);
100445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
100475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just check a grab bag of cert errors.
100485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kErrors[] = {
100495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_COMMON_NAME_INVALID,
100505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_AUTHORITY_INVALID,
100515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_DATE_INVALID,
100525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kErrors); i++) {
100545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], ASYNC);
100555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
100565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
100575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
100605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
100615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
100625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is disabled.
100635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
100645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
100657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
100665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_NoFalseStart) {
100675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
100685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
100695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
100705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
100715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
100735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cert_request->host_and_port = "www.example.com:443";
100745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 contains the data for the first SSL handshake. When a
100765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CertificateRequest is received for the first time, the handshake will
100775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be aborted to allow the caller to provide a certificate.
100785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
100795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
100815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
100835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data2 contains the data for the second SSL handshake. When TLS
100855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // False Start is not being used, the result of the SSL handshake will be
100865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned as part of the SSLClientSocket::Connect() call. This test
100875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // matches the result of a server sending a handshake_failure alert,
100885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // rather than a Finished message, because it requires a client
100895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate and none was supplied.
100905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
100915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
100935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
100955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data3 contains the data for the third SSL handshake. When a
100975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
100985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
100995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1.1. This is transparent to the caller
101005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
101015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
101025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
101035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
101045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
101065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
101085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 contains the data for the fourth SSL handshake. When a
101105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
101115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
101125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1. This is transparent to the caller
101135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
101145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
101155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
101165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
101175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
101195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
101215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
101302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
101325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the SSL handshake with the peer. This consumes ssl_data1.
101345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
101355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
101365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
101375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
101395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
101405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
101415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
101425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
101445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
101455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
101465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
101475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
101485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
101495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
101515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
101525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
101535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
101545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       &client_cert));
101555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
101565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
101585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
101595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
101605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
101615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
101625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
101645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
101655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
101665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        &client_cert));
101675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
101685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
101705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
101715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
101725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is enabled.
101735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
101745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
101757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
101765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_FalseStart) {
101775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
101785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
101795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
101805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
101815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
101835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cert_request->host_and_port = "www.example.com:443";
101845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When TLS False Start is used, SSLClientSocket::Connect() calls will
101865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return successfully after reading up to the peer's Certificate message.
101875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is to allow the caller to call SSLClientSocket::Write(), which can
101885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enqueue application data to be sent in the same packet as the
101895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChangeCipherSpec and Finished messages.
101905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual handshake will be finished when SSLClientSocket::Read() is
101915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which expects to process the peer's ChangeCipherSpec and
101925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finished messages. If there was an error negotiating with the peer,
101935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // such as due to the peer requiring a client certificate when none was
101945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied, the alert sent by the peer won't be processed until Read() is
101955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called.
101965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Like the non-False Start case, when a client certificate is requested by
101985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the peer, the handshake is aborted during the Connect() call.
101995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 represents the initial SSL handshake with the peer.
102005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
102015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
102035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
102055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When a client certificate is supplied, Connect() will not be aborted
102075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the peer requests the certificate. Instead, the handshake will
102085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // artificially succeed, allowing the caller to write the HTTP request to
102095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the socket. The handshake messages are not processed until Read() is
102105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which then detects that the handshake was aborted, due to the
102115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // peer sending a handshake_failure because it requires a client
102125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate.
102135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
102145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
102165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockRead data2_reads[] = {
102175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
102185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
102195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(
102205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
102225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
102245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the data for the SSL handshake once the TLSv1.1 connection falls back to
102255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TLSv1. It has the same behaviour as [ssl_]data2.
102265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
102275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
102295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(
102305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
102325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
102345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
102355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
102365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
102385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(
102395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
102415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(
10247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the initial SSL handshake.
102555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
102565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
102575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
102585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
102605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
102615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
102625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
102635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
102655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
102665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
102675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
102685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
102695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
102705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
102725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
102735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
102745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
102755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       &client_cert));
102765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
102775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
102795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
102805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
102815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
102825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
102835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
102855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
102865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
102875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        &client_cert));
102885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
102915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
102925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) An HTTPS proxy is involved.
102935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The HTTPS proxy requests a client certificate.
102945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate for the
102955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     proxy.
102965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test is repeated twice, first for connecting to an HTTPS endpoint,
102975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then for connecting to an HTTP endpoint.
102987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
103005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
103015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
103035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
103055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cert_request->host_and_port = "proxy:70";
103065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
103085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data[1-3]. Rather than represending the endpoint
103095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (www.example.com:443), they represent failures with the HTTPS proxy
103105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (proxy:70).
103115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
103125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
103145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
103165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
103185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
103205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
103225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
103245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
103255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
103265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
103285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
103305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
103315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo requests[2];
103335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].url = GURL("https://www.example.com/");
103345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].method = "GET";
103355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].load_flags = net::LOAD_NORMAL;
103365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].url = GURL("http://www.example.com/");
103385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].method = "GET";
103395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].load_flags = net::LOAD_NORMAL;
103405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(requests); ++i) {
10342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
10343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
103445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans(
10345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
103465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Begin the SSL handshake with the proxy.
103485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
103495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(
103505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &requests[i], callback.callback(), net::BoundNetLog());
103515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
103525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Complete the SSL handshake, which should abort due to requiring a
103545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // client certificate.
103555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
103565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
103575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicate that no certificate should be supplied. From the perspective
103595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of SSLClientCertCache, NULL is just as meaningful as a real
103605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate, so this is the same as supply a
103615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // legitimate-but-unacceptable certificate.
103625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithCertificate(NULL, callback.callback());
103635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
103645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was added to the client auth cache before
103665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // allowing the connection to continue restarting.
103675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<X509Certificate> client_cert;
103685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
103695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         &client_cert));
103705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(NULL, client_cert.get());
103715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was NOT cached for the endpoint. This only
103725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // applies to HTTPS requests, but is fine to check for HTTP requests.
103735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
103745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          &client_cert));
103755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart the handshake. This will consume ssl_data2, which fails, and
103775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then consume ssl_data3, which should also fail. The result code is
103785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // checked against what ssl_data3 should return.
103795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
103805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
103815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now that the new handshake has failed, ensure that the client
103835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate was removed from the client auth cache.
103845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
103855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          &client_cert));
103865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
103875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          &client_cert));
103885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
103895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
103905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Unlike TEST/TEST_F, which are macros that expand to further macros,
103927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TEST_P is a macro that expands directly to code that stringizes the
103937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// arguments. As a result, macros passed as parameters (such as prefix
103947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// or test_case_name) will not be expanded by the preprocessor. To
103957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// work around this, indirect the macro for TEST_P, so that the
103967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// pre-processor will expand macros such as MAYBE_test_name before
103977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// instantiating the test.
103987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define WRAPPED_TEST_P(test_case_name, test_name) \
103997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TEST_P(test_case_name, test_name)
104007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
104015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
104025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
104035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
104045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
104055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
104065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
104077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
104085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
104095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
104105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
10413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
104145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
104155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
104165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
104187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
104205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1042190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1042290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1042390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1042490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
104255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
104265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
104275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
104285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
104307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
104317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
104327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
104337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
104347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
104357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
104367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
104375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
104385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
104395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
104405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
104415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
104425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
104435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
104465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
104475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
104485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
104495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
104505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
104515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
104525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
104545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
104565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
104575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
104585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
104595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
104615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
104635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
104645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
104655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
104675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
104695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
104705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
104725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
104735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
104745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload www.gmail.com into HostCache.
104765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port("www.gmail.com", 443);
104775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(host_port);
104785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
10479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(resolve_info, &ignored,
104802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           callback.callback(), NULL,
104812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           BoundNetLog());
104825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
104835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
104845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
104855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
104875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
104885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
104895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
104915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
104935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
104945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
104955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
104975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
104995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
105005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
105015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
105025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
105035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
105045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPooling
105065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
105085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
105095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
105105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
10513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
105155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
105165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
105187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
105205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1052290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1052390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1052490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
105255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
105265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
105275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
105285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
105307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
105317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
105327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
105337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
105347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
105357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
105367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
105375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
105385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
105395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
105405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
105415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
105425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
105435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
105465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
105475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
105485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
105495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
105505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
105515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
105525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
105545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
105565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
105575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
105585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
105595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
105615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
105635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
105645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
105655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
105675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
105695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
105705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
105725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
105735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
105745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
105765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
105775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
105785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
105805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
105825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
105835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
105845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
105865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
105885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
105895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
105905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
105915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
105925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
105935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OneTimeCachingHostResolver : public net::HostResolver {
105965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
105975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
105985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : host_port_(host_port) {}
105995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OneTimeCachingHostResolver() {}
106005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
106025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HostResolver methods:
106045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Resolve(const RequestInfo& info,
106055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      AddressList* addresses,
106065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const CompletionCallback& callback,
106075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      RequestHandle* out_req,
106085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const BoundNetLog& net_log) OVERRIDE {
106095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return host_resolver_.Resolve(
106105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info, addresses, callback, out_req, net_log);
106115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int ResolveFromCache(const RequestInfo& info,
106145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               AddressList* addresses,
106155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const BoundNetLog& net_log) OVERRIDE {
106165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
106175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == OK && info.host_port_pair().Equals(host_port_))
106185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_.GetHostCache()->clear();
106195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
106205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(RequestHandle req) OVERRIDE {
106235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_resolver_.CancelRequest(req);
106245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver* GetMockHostResolver() {
106275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &host_resolver_;
106285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
106315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver host_resolver_;
106325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HostPortPair host_port_;
106335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
106345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
106365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
10637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
106395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
10640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UseIPConnectionPoolingWithHostCacheExpiration
106425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
106437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest,
106447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
106457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
106467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// prefix doesn't work with parametrized tests).
106477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
106487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return;
106497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
106507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
106515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_use_alternate_protocols(true);
106525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
106535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
106555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
106562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpNetworkSession::Params params =
10657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::CreateSessionParams(&session_deps_);
106585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.host_resolver = &host_resolver;
10659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
106605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
106615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
106625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
106647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
106665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1066790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1066890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1066990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1067090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
106715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
106725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
106735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
106745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
106757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
106767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
106777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
106787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
106797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
106807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
106817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
106827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
106835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
106845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
106855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
106865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
106875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
106885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
106895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
106905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
106925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
106935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
106945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
106955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
106965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
106975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
106985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
107005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
107025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
107035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
107045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
107055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
107075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
107095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
107105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
107115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
107135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
107155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
107165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
107185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
107195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
107205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload cache entries into HostCache.
107225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
107235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
107242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = host_resolver.Resolve(resolve_info, &ignored, callback.callback(),
107252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             NULL, BoundNetLog());
107265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
107275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
107285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
107295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
107315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
107325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
107335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
107355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
107375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
107385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
107395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
107415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
107435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
107445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
107455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
107465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
107475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
107485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
107495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
107505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
107525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
107535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
107545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
107565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
107575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
107585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
107595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
107615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
107625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider* data[] = { &data1, &data2 };
107635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
107655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
107675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
107685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
107695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
107705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
107725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
107735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
107745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
107765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
107775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
107785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
107795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
107815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
107825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
107835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
107845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(NULL, 0,
107865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
107875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
107885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
107895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider* data[] = { &data1, &data2 };
107905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
107925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
107945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
107955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
107965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
107975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
107995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
108005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
108015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1080390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1080490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
108055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
108075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
108085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
108095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
108117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
108125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
108135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
108145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
108155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 3)
108165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
108175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data1(
108195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads1, arraysize(reads1),
108205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes1, arraysize(writes1));
108215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
108225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
108235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP GET for the HTTP URL
108255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
108265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 4,
108275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "GET / HTTP/1.1\r\n"
108285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com:443\r\n"
108295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
108305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
108315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
108335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
108345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 6, "hello"),
108355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 7, OK),
108365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
108375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data2(
108395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads2, arraysize(reads2),
108405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes2, arraysize(writes2));
108415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
108437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
10846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
108475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
108495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
108515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
108525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
108535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
108545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
108565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
108575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
108585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1085990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
108605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
108625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
108635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
108655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
108665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
108675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
108685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
108705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
108715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
108725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1087390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
108745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
108765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
108775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
108785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
108805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
108815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
108825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (through CONNECT tunnel)
1088490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
1088590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1088690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
108875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
108897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_req1(
108907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
108915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const headers[] = {
108927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetMethodKey(), "GET",
108937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
108947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetHostKey(),  "www.google.com:443",
108957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetSchemeKey(), "http",
108967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetVersionKey(), "HTTP/1.1"
108975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10898a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
10899a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
10900a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      headers, arraysize(headers), 0));
109015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
109035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect, 0),
109045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_req1, 2),
109055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 5),
109065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
109097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
109107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
109117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
109127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_resp1(
109137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
109147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
109157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
109167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
109177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
109185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
109195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 1),
109205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_resp1, 3),
109215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body1, 4),
109225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 6),
109235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 7),
109245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 8)
109255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeterministicSocketData data1(reads1, arraysize(reads1),
109285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                writes1, arraysize(writes1));
109295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
109305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
109315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
109332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
109342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
10935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
109365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
109377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
10938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
109395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
109407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
10941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
10942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
109435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
10945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
109465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
109485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
109495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
109505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
109515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
109535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
109545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
109555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1095690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
109575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(4);
109585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
109605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
109615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
109632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
109642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
109652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
109662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
109675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
109685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
109695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
109705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
109715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
10972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
109735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
109745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
109755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1097690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
109775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(3);
109785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
109805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
109812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
109822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
109832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
109842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The established SPDY sessions is considered reused by the HTTP request.
109852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
109862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HTTP requests over a SPDY session should have a different connection
109872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // socket_log_id than requests over a tunnel.
109882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
109895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
109905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
109925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory::set_force_spdy_always(true);
109935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
109945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
109955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1099790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1099890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
109995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for the HTTP URL
1100090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1100190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
110025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
110045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 1),
110055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 4),
110065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
110097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
110107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
110117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
110125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
110135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 2),
110145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 3),
110155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 5),
110165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 6),
110175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 7)
110185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
110215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
110225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
110247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
110275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
110295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
110315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
110325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
110335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
110345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
110365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
110375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
110385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1103990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
110405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
110425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
110435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
110455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
110465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
110475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
110485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
110505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
110515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
110525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1105390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
110545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
110565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
110575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
110585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that in the case where we have a SPDY session to a SPDY proxy
110605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we do not pool other origins that resolve to the same IP when
110615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the certificate does not match the new origin.
110625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/134690
110637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
110645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url1 = "http://www.google.com/";
110655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url2 = "https://mail.google.com/";
110665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string ip_addr = "1.2.3.4";
110675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTP URL (through SPDY proxy)
110697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
110707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11071a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
110727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
110735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
110755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
110765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
110797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
110805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
110815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
110825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
110835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
110845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
110875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1),
110885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes1, arraysize(writes1)));
110895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
110905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
110915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
110925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK, peer_addr);
110935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->set_connect_data(connect_data1);
110945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (direct)
1109690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1109790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
110985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
111005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 0),
111015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
111025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
111047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
111055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
111065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 1),
111075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 2),
111085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
111095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
111105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
111125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
111135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes2, arraysize(writes2)));
111145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data2(ASYNC, OK);
111155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->set_connect_data(connect_data2);
111165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a proxy config that sends HTTP requests to a proxy, and
111185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all others direct.
111195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
111205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
111215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
111225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
11123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
111245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
111255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
111265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load a valid cert.  Note, that this does not need to
111285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be valid for proxy because the MockSSLClientSocket does
111295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not actually verify it.  But SpdySession will use this
111305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to see if it is valid for the new origin
111312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
111325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> server_cert(
111335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
111345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
111355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
111377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
111385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl1.cert = server_cert;
11139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
111425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
111447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
111485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
111525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
111555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
111575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
111585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
111595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(url1);
111605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
111625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
111635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
111645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
111655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->RunFor(3);
111665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback1.have_result());
111685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
111695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
111705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
111725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
111735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
111745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(url2);
111755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
111775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
111785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
111795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1118090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
111815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->RunFor(3);
111825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
111845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
111855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
111865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
111875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// error) in SPDY session, removes the socket from pool and closes the SPDY
11190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// session. Verify that new url's from the same HttpNetworkSession (and a new
11191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SpdySession) do work. http://crbug.com/224701
111927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string https_url = "https://www.google.com/";
11194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads1[] = {
11196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
11200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data1->SetStop(1);
11202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1120390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1120490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes2[] = {
11206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockWrite(*req2, 0),
11207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
112107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads2[] = {
11212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*resp2, 1),
11213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*body2, 2),
11214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, OK, 3)  // EOF
11215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
11218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
11219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  writes2, arraysize(writes2)));
11220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
112227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
11226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
112287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
11232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start the first transaction to set up the SpdySession and verify that
11237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // connection was closed.
11238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request1;
11239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.method = "GET";
11240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.url = GURL(https_url);
11241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.load_flags = 0;
11242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(MEDIUM, session.get());
11243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback1;
11244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1124690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now, start the second request and make sure it succeeds.
11250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request2;
11251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.method = "GET";
11252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.url = GURL(https_url);
11253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.load_flags = 0;
11254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
11255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback2;
11256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1125890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data2->RunFor(3);
11260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
11262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
11263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
11265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11267a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11268a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
11269a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11270a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
11271a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11272a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11273a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Use two different hosts with different IPs so they don't get pooled.
11274a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11275a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11276a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11277a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
112797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11280a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
112817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11282a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11283a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11284a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1128590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11286a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11287a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy1_writes[] = {
11288a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host1_req, 1),
11289a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
112907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
112917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
112927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
112937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11294a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy1_reads[] = {
11295a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp, 2),
11296a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
11297a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11298a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11299a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11300a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy1_data(
11301a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11302a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_reads, arraysize(spdy1_reads),
11303a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_writes, arraysize(spdy1_writes)));
11304a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11305a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1130690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11307a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11308a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy2_writes[] = {
11309a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host2_req, 1),
11310a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
113117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
113127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
113137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
113147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11315a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy2_reads[] = {
11316a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp, 2),
11317a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp_body, 3),
11318a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11319a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11320a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11321a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy2_data(
11322a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11323a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_reads, arraysize(spdy2_reads),
11324a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_writes, arraysize(spdy2_writes)));
11325a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11326a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11327a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite http_write[] = {
11328a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
11329a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Host: www.a.com\r\n"
11330a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
11331a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11332a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11333a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead http_read[] = {
11334a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
11335a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11336a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Length: 6\r\n\r\n"),
11337a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("hello!"),
11338a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11339a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11340a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                     http_write, arraysize(http_write));
11341a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11342a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11343a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a("www.a.com", 443);
1134490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a(
1134590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
11346a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
113477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11348a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11349a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TestCompletionCallback callback;
11350a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request1;
11351a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.method = "GET";
11352a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.url = GURL("https://www.a.com/");
11353a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.load_flags = 0;
11354a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
11355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11356a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11357a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11358a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11359a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11360a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11361a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11362a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11364a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11365a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11366a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11367a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11368a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string response_data;
11369a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11370a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11371a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  trans.reset();
11372a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
113737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11374a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11375a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_b("www.b.com", 443);
1137690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_b(
1137790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
11378a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
113797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11380a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request2;
11381a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.method = "GET";
11382a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.url = GURL("https://www.b.com/");
11383a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.load_flags = 0;
11384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11385a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11386a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11387a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11388a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11389a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11390a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11391a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11393a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11394a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11395a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11396a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11397a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11398a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
113997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11400a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
114017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11402a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11403a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a1("www.a.com", 80);
1140490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a1(
1140590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
11406a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
114077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11408a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request3;
11409a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.method = "GET";
11410a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.url = GURL("http://www.a.com/");
11411a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.load_flags = 0;
11412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11413a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11414a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11415a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11417a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11418a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11419a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11421a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11422a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
11423a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
11424a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11425a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11426a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
114277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11428a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
114297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11430a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
11431a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
11439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY,
11440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 CreateSession(&session_deps_)));
11441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
11469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY,
11470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 CreateSession(&session_deps_)));
11471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
11499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY,
11500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 CreateSession(&session_deps_)));
11501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
11507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
11535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY,
11536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 CreateSession(&session_deps_)));
11537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(ASYNC, ERR_CONNECTION_RESET),
11540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
11543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
11571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY,
11572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 CreateSession(&session_deps_)));
11573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
11576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
11577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
11578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
11609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY,
11610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 CreateSession(&session_deps_)));
11611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
11614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
11615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
11616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_CONNECTION_RESET),
11619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
11638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.extra_headers.SetHeader("X-Foo", "bar");
11646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
11648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY,
11649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 CreateSession(&session_deps_)));
11650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
11653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
11654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n"
11655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "X-Foo: bar\r\n\r\n"),
11656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
11658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead("HTTP/1.1 200 OK\r\n"
11659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "Content-Length: 5\r\n\r\n"
11660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "hello"),
11661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_UNEXPECTED),
11662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
11666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(OK, rv);
11675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string foo;
11679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("bar", foo);
11681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
116835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
11684